首先先理解一下golang http.request的三个属性Form、PostForm、MultipartForm,然后才能很好的理解,简要说明如下:

  • Form:存储了post、put和get参数,在使用之前需要调用ParseForm方法。
  • PostForm:存储了post、put参数,在使用之前需要调用ParseForm方法。
  • MultipartForm:存储了包含了文件上传的表单的post参数,在使用前需要调用ParseMultipartForm方法。

获取GET参数

网上比较常见的一个版本是:

r.ParseForm()
if len(r.Form["name"]) > 0 {
        fmt.Fprintln(w, r.Form["name"][0])
}

其中r表示*http.Request类型,w表示http.ResponseWriter类型。r.Form是url.Values字典类型,r.Form["id"]取到的是一个数组类型。因为http.request在解析参数的时候会将同名的参数都放进同一个数组里,所以这里要用[0]获取到第一个。

这种取法在通常情况下都没有问题,但是如果是如下请求则无法取到需要的值:

<form action="http://127.0.0.1:9090/?name=mark" method="POST">
    <input type="text" name="name" value="best" />
    <input type="submit" value="submit" />
</form>

因为r.Form包含了get和post参数,并且以post参数为先,上例post参数和get参数都有id,所以应当会取到post参数2。虽然这种情况并不多见,但是从严谨的角度来看程序上还是应当处理这种情况:

queryForm, err := url.ParseQuery(r.URL.RawQuery)
if err == nil && len(queryForm["name"]) > 0 {
        fmt.Fprintln(w, queryForm["name"][0])
}

代码比较简单,就是分析url问号后的参数。事实上这个也是标准库ParseForm中关于get参数解析代码。

获取POST参数

这里要分两种情况:

  • 普通的post表单请求,Content-Type=application/x-www-form-urlencoded
  • 有文件上传的表单,Content-Type=multipart/form-data

第一种情况比较简单,直接用PostFormValue就可以取到了:

r.ParseForm()
fmt.Fprintln(w, r.PostFormValue("name"))

第二种情况复杂一些,如下表单:

<form action="http://127.0.0.1:9090" method="POST" enctype="multipart/form-data">
    <input type="text" name="name" value="markbest" />
    <input type="file" name="pic" />
    <input type="submit" value="submit" />
</form>

因为需要上传文件,所以表单enctype要设置成multipart/form-data,此时需要使用ParseMultipartForm方可解析:

r.ParseMultipartForm(32 << 20)
fmt.Println(r.PostForm)
fmt.Println(r.MultipartForm.File)

这样子就能获取post参数以及上传的文件参数。

results matching ""

    No results matching ""