上一节曾经提到过,为了提取表单传递的键值对数据,用户可能需要亲自对服务器接收到的未经处理的表单数据进行语法分析。但事实上,因为net/http库已经提供了一套用途相当广泛的函数,这些函数一般都能够满足用户对数据提取方面的需求,所以我们很少需要自行对表单数据进行语法分析。

通过调用Request结构提供的方法,用户可以将URL主体又或者以上两者记录的数据提取到该结构的FormPostFormMultipartForm等字段当中。跟我们平常通过POST请求获取到的数据一样,存储在这些字段里面的数据也是以键值对形式表示的。使用Request结构的方法获取表单数据的一般步骤是:

  1. 调用ParseForm方法或者ParseMultipartForm方法,对请求进行语法分析。
  2. 根据步骤1调用的方法,访问相应的Form字段、PostForm字段或MultipartForm字段。

代码清单4-4展示了一个使用ParseForm方法对表单进行语法分析的例子。

代码清单4-4 对表单进行语法分析

package main

import (    
    "fmt"    
    "net/http"
)

func process(w http.ResponseWriter, r *http.Request) {    
    r.ParseForm()    
    fmt.Fprintln(w, r.Form)
}

func main() {    
    server := http.Server{        
        Addr: "127.0.0.1:8080",
    }
    http.HandleFunc("/process", process)
    server.ListenAndServe()
}

这段代码中最重要的就是下面这两行:

r.ParseForm()
fmt.Fprintln(w, r.Form)

如前所述,这段代码首先使用了ParseForm方法对请求进行语法分析,然后再访问Form字段,获取具体的表单。

现在,让我们来创建一个短小精悍的HTML表单,并使用它作为客户端,向代码清单4-4所示的服务器发送请求。请创建一个名为client.html的文件,并将以下代码复制到该文件中:

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>GoWebProgramming</title>
    </head>
    <body>
        <form action=http://127.0.0.1:8080/process?hello=world&thread=123 
            method="post" enctype="application/x-www-form-urlencoded">
            <input type="text" name="hello" value="sau sheong"/>      
            <input type="text" name="post" value="456"/>      
            <input type="submit"/>    
        </form>  
    </body>
</html>

这个HTML表单可以完成以下工作:

  • 通过POST方法将表单发送至地址http://localhost:8080/process?hello=world&thread=123
  • 通过enctype属性将表单的内容类型设置为application/x-www-form-urlencoded
  • hello=sau sheongpost=456这两个HTML表单键值对发送至服务器。

需要注意的是,这个表单为相同的键hello提供了两个不同的值,其中,值world是通过URL提供的,而值sau sheong则是通过HTML表单中的文本输入行提供的。

因为客户端可以直接在浏览器上运行,所以我们并不需要使用服务器来为客户端提供服务:我们要做的就是使用浏览器打开client.html文件,然后点击表单中的发送按钮。如果一切正常,浏览器应该会显示以下输出:

map[thread:[123] hello:[sau sheong world] post:[456]]

这是服务器在对请求进行语法分析之后,使用字符串形式显示出来的未经处理的Form结构。这个结构是一个映射,它的键是字符串,而键的值是一个由字符串组成的切片。因为映射是无序的,所以你看到的键值对排列顺序可能和这里展示的有所不同。但是无论如何,这个映射总是会包含查询值hello=worldthread=123,还有表单值hello=sau sheongpost=456。正如所见,这些值都进行了相应的URL解码,比如在sausheong之间就能够正常地看到空格,而不是编码之后的%20

results matching ""

    No results matching ""