打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Go Web 中的 Form

在 Go 中, http.Request 上的函数可以从 URLBody 中提取数据,通过 Form 字段、 PostForm 字段、 MultipartForm 字段可以提取表单数据。这一期我们就讲一讲这几个字段。

Form 字段

Form 里面的数据是键值对(key-value对)。

一般我们先调用 ParseFormParseMultipartForm 方法来解析 Request 。然后相应地访问 Form 字段、 PostForm 字段或 MultipartForm 字段来获取表单数据。

下面我们举个例子,首先创建一个 index.html 文件,主要用于创建表单,例子中创建了两个输入框,一个是用于输入 id ,另一个用于输入 name

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Go Web Form</title>
</head>
<body>
    <form action="http://localhost:8080/" method="post" enctype="application/x-www-form-urlencoded">
        <input type="text" name="id" />
        <input type="text" name="name" />
        <input type="submit" />
    </form>
</body>
</html>

然后我们编写 main.go 文件,对提交的表单数据进行解析并输出:

package main

import (
 "fmt"
 "net/http"
)

func main() {
 server := http.Server{
  Addr: "localhost:8080",
  Handler: nil,
 }

 http.HandleFunc("/"func(w http.ResponseWriter, r *http.Request) {
        // 解析
  r.ParseForm()
        // 输出
  fmt.Fprintln(w, r.Form)
 })

 server.ListenAndServe()
}

运行程序,打开刚刚写好的 HTML 网页,在表单中输入数据,这里的 id 填入的是 123name 填入的是 caizi

点击提交,转到 http://localhost:8080/ 显示了刚刚我们表单输入的数据:

map[id:[123] name:[caizi]]

通过数据可以看出, r.Form 字段其实就是一个 map ,这里面有两个 key 分别是 idname ,对应的值是一个字符串切片,分别是 [123][caizi] 。这里注意,每个 key 可以对应多个值,而且 map 里面数据的顺序是不一定的。

通过源码我们也可以知道, Form 是 url.Values 类型的:

Form url.Values

url.Values 实际上是一个 map ,其键是 string 类型的,而值是 []string 类型的:

type Values map[string][]string


PostForm 字段

如果我们只想得到某个 key 的 value ,可以使用 r.Form["key"] ,其返回含有一个元素的 slice ,例如刚刚上面的例子,调用 r.Form["name"] 会返回 ["caizi"]

上面我们也提到过,每个 key 可以对应多个 value ,如果表单和 URL 里有同样的 key ,那么它们都会放在一个 slice 里,但表单里的值会靠前,而 URL 的值会靠后。

还是上面那个例子,我们对 index.html 进行修改:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Go Web Form</title>
</head>
<body>
    <form action="http://localhost:8080/?id=456" method="post" enctype="application/x-www-form-urlencoded">
        <input type="text" name="id" />
        <input type="text" name="name" />
        <input type="submit" />
    </form>
</body>
</html>

这里 URL 添加了参数, http://localhost:8080/?id=456id=456 ,同样打开网页填入刚刚的数据,会有下面的结果:

map[id:[123 456] name:[caizi]]

而如果只想要表单的键值对,而不想要 URL 的,可以使用 PostForm 字段。还是刚刚修改后的 index.html 文件,但把 main.go 中的 r.Form 修改成 r.PostForm ,运行后还是在表单中输入之前的数据,提交后如下:

map[id:[123] name:[caizi]]

可以看到只获取了表单的键值对。

但注意 PostForm 只支持 enctypeapplication/x-www-form-urlencoded 的情况。想要得到 multipart 键值对,必须使用 MultipartForm 字段

MultipartForm 字段

想要使用 MultipartForm 这个字段的话,首先需要调用 ParseMultipartForm 这个方法,这个方法需要一个参数,参数是需要读取数据的长度, int64 类型,单位是字节数。这个方法会在必要时自动调用 ParseForm 方法。MultipartForm 只包含表单的键值对。

该方法返回类型是一个 struct 而不是 map 。这个 struct 里有两个 map :

  • 一个 map 的 key 是 string ,而 value 是 []string 。
  • 另一个 map 是空的(其 key 是 string ,而 value 是文件,用于传文件)。

接下来我们把 index.html 中的 enctype 改成 multipart/form-data

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Go Web Form</title>
</head>
<body>
    <form action="http://localhost:8080/?id=456" method="post" enctype="multipart/form-data">
        <input type="text" name="id" />
        <input type="text" name="name" />
        <input type="submit" />
    </form>
</body>
</html>

main.go 文件中的 r.ParseForm() 改成 r.ParseMultipartForm(1024) ,把 fmt.Fprintln(w, r.Form) 改成 fmt.Fprintln(w, r.MultipartForm)

package main

import (
 "fmt"
 "net/http"
)

func main() {
 server := http.Server{
  Addr: "localhost:8080",
  Handler: nil,
 }

 http.HandleFunc("/"func(w http.ResponseWriter, r *http.Request) {
  r.ParseMultipartForm(1024)
  fmt.Fprintln(w, r.MultipartForm)
 })

 server.ListenAndServe()
}

还是跟上面一样运行程序后打开 index.html 文件输入数据,提交后结果如下:

&{map[id:[123] name:[caizi]] map[]}

可以看到结果是一个结构体,里面有两个 map ,跟上面提到的一致。

👇希望对你有帮助,期待你的关注👇

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
curl网站开发指南
django基础二
HTTP协议与HTML表单(再谈GET与POST的区别)
HTML之form表单ENCTYPE属性解析
Form Effect - 表单美化插件(2)
HTTP 冷知识 | HTTP 请求中,空格应该被编码为 %20 还是 + ?
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服