获取参数
我们经常需要获取用户传递的数据,包括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>