擷取參數
我們經常需要擷取使用者傳遞的資料,包括
GET
、
POST
等方式的請求。你可以通過如下方式擷取資料:
通過
r.Form.Get("參數名")
、
r.PostForm.Get("參數名")
擷取對應字段的值,r表示伺服器接收或由用戶端發送的
HTTP
請求。在Go标準包
net/http
中的
request.go
檔案中可以看到該結構體的定義,其中與今天讨論有關的字段有
type Request struct {
Body io.ReadCloser
Form url.Values
PostForm url.Values
MultipartForm *multipart.Form
}
Body
字段後面的這三個字段都需要依賴其他方法,前兩者需要調用
ParseForm()
方法,後者需要調用
ParseMultipartForm()
方法。
- 對于所有的請求,
從ParseForm
解析原始查詢,對于URL
、POST
和PUT
請求,它還會将請求解析為表單,并将結果放入PATCH
和r.PostForm
中。請求r.Form
參數優先于body
中的r.Form
URL
查詢字元串值。
對于其他
方法,或者當HTTP
不是Content-Type
時,該方法不會讀取請求application/x-www-form-urlencoded
,同時也不會将body
r.PostForm
初始化為非零空值。
如果請求
的大小沒有提前限定,那麼它的最大值為body
。10MB
-
解析表單屬性ParseMultipartForm
是enctype
的内容。multipart/form-data
,調用func (r *Request) ParseMultipartForm(maxMemory int64) error
之後,上傳的檔案存儲在ParseMultipartForm
大小的記憶體裡面,如果檔案大小超過了maxMemory
,那麼剩下的部分将存儲在系統的臨時檔案中。maxMemory
直接解析到struct
當請求不能用上面的方法擷取時,可以使用
ioutil.ReadAll(r.Body)
讀取請求中的
body
。再通過
struct
的字段名或
tag
與
body
中對應字段直接解析到
struct
。定義
struct
時,字段名後如果有
form
這個
tag
,則會以把
form
表單裡的
name
和
tag
的名稱一樣的字段指派給這個字段,否則就會把
form
表單裡與字段名一樣的表單内容指派給這個字段。
如果要忽略一個字段,有兩種辦法:一是字段名小寫開頭,二是
form
标簽的值設定為
-
。
完整代碼
main.go
package main
import (
"net/http"
"fmt"
"io/ioutil"
"encoding/json"
"html/template"
)
type Test struct {
NickName string `json:"nickname"`
Phone string `json:"phone"`
PassWord string `json:"password"`
}
func main() {
http.HandleFunc("/test", testFunc)
http.HandleFunc("/testdata", testData)
http.ListenAndServe(":8000", nil)
}
func testFunc(w http.ResponseWriter, r *http.Request) {
t, _ := template.ParseFiles("templates/test.html")
t.Execute(w, nil)
}
func testData(w http.ResponseWriter, r *http.Request) {
var test Test
r.ParseForm()
test.NickName = r.Form.Get("nickname")
if test.NickName == "" {
data, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Println(err)
return
}
err = json.Unmarshal(data, &test)
if err != nil {
fmt.Println(err)
return
}
fmt.Fprintf(w, "====>%s %s %s", test.NickName, test.Phone, test.PassWord)
} else {
test.Phone = r.Form.Get("phone")
test.PassWord = r.Form.Get("password")
fmt.Fprintf(w, "%s %s %s", test.NickName, test.Phone, test.PassWord)
}
}
test.html
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>test</title>
</head>
<body>
<form action="/testdata" method="post">
NickName:<br>
<input type="text" name="nickname" value="請輸入昵稱">
<br>
Phone:<br>
<input type="text" name="phone" value="請輸入手機号">
<br>
PassWord:<br>
<input type="text" name="password" value="請輸入密碼">
<br><br>
<input type="submit" value="submit">
</form>
</body>
</html>