Go HTTP Web接收HTML表單上傳的資料及上傳檔案。
範例環境:
- Go 1.18
表單
建立下面HTML表單來提交資料。因為要上傳檔案所以<form>
的enctype
屬性設為multipart/form-data
。
demo.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form action="http://localhost:8080/employee" method="POST" enctype="multipart/form-data">
name:<input name="name" type="text" value="John"><br>
email:<input name="email" type="email" value="john@abc.com"><br>
age:<input name="age" type="number" value="33"><br>
birthday:<input name="birthday" type="date" value="1989-04-12"><br>
gender:
<label><input type="radio" name="gender" value="male" checked>male</label>
<label><input type="radio" name="gender" value="female">female</label>
<label><input type="radio" name="gender" value="others">others</label>
<br>
languages:
<label><input type="checkbox" name="lang" value="en">english</label>
<label><input type="checkbox" name="lang" value="ch" checked>mandarin</label>
<label><input type="checkbox" name="lang" value="jp" checked>japanese</label>
<br>
photo:<input name="photo" type="file"><br>
<input type="submit">
</form>
</body>
</html>
取得表單資料
下面建立一個POST|/employee
API接收從表單上傳的檔案。要先調用http.Requset.ParseMultipartForm()
才能從http.Request.Form
以欄位名取得表單資料及以http.Request.FormFile
取得檔案。然後將取得檔案存放在專案根目錄下。
http.Requset.ParseMultipartForm()
輸入參數為記憶體大小,即暫存表單及檔案的空間大小,這邊1 << 20
(位移運算)相當於二進制的100000000000000000000,為2的20次方(220),也就是1024x1024,也就是1MB。
main.go
package main
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
)
func main() {
http.HandleFunc("/employee", func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPost:
r.ParseMultipartForm(1 << 20) // 1MB
name := r.Form.Get("name")
email := r.Form.Get("email")
age := r.Form.Get("age")
birthday := r.Form.Get("birthday")
gender := r.Form.Get("gender")
langs := r.Form["lang"]
file, header, err := r.FormFile("photo")
if err != nil {
panic(err)
}
defer file.Close()
buf := bytes.NewBuffer(nil)
_, err = io.Copy(buf, file)
if err != nil {
panic(err)
}
filename := header.Filename
err = ioutil.WriteFile(filename, buf.Bytes(), 0666)
if err != nil {
panic(err)
}
fmt.Fprint(w, fmt.Sprintf(
"name=%v\nemail=%v\nage=%v\nbirtyday=%v\ngender=%v\nlanguages=%v\nphoto=%v",
name, email, age, birthday, gender, langs, filename))
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
})
http.ListenAndServe(":8080", nil)
}
測試
啟動專案,在瀏覽器輸入資料如下,並上傳一個gopher.jpg
。
點選Submit提交結果如下。
或用curl發送表單請求如下。
curl -X POST "http://localhost:8080/employee" -H 'content-type: multipart/form-data' -F 'name=John' -F 'email=john@abc.com' -F 'age=33' -F 'birthday=1989-04-12' -F 'gender=male' -F 'lang=en,ch,jp' -F 'photo=@./gopher.jpg'
content-type
設為multipart/form-data
;欄位使用-F '<name>=<value>'
輸入;上傳檔案使用-F '<name>=@<filepath>'
。<name>
為input名稱,範例為file
filepath
為上傳檔案的目錄位置,範例為執行curl同目錄下的gopher.jpg
。
$ curl -X POST "http://localhost:8080/employee" \
> -H 'content-type: multipart/form-data' \
> -F 'name=John' \
> -F 'email=john@abc.com' \
> -F 'age=33' \
> -F 'birthday=1989-04-12' \
> -F 'gender=male' \
> -F 'lang=en,ch,jp' \
> -F 'photo=@./gopher.jpg'
回應結果。
name=John
email=john@abc.com
age=33
birtyday=1989-04-12
gender=male
languages=[en,ch,jp]
photo=gopher.jpg
沒有留言:
張貼留言