黑马程序员技术交流社区

标题: 【文章】request的参数 [打印本页]

作者: 小蜀哥哥    时间: 2019-12-12 13:11
标题: 【文章】request的参数
Request结构

Request结构主要由以下部分组成
URL字段
Header字段
Body字段
Form字段、PostForm字段和MultipartForm字段
[HTML] 纯文本查看 复制代码

type Request struct {

        Method string

        URL *url.URL

        Proto      string // "HTTP/1.0"

        ProtoMajor int    // 1

        ProtoMinor int    // 0

        Header Header

        Body io.ReadCloser

        GetBody func() (io.ReadCloser, error)

        ContentLength int64

        TransferEncoding []string

        Close bool

        Host string

        Form url.Values

        PostForm url.Values

        MultipartForm *multipart.Form

        Trailer Header

        RemoteAddr string

        RequestURI string

        TLS *tls.ConnectionState

        Cancel <-chan struct{}

        Response *Response

        ctx context.Context

}

请求URL

Request结构中的URL字段用于表示请求行中包含的URL

[JavaScript] 纯文本查看 复制代码
type URL struct {

        Scheme     string

        Opaque     string    // encoded opaque data

        User       *Userinfo // username and password information

        Host       string    // host or host:port

        Path       string    // path (relative paths may omit leading slash)

        RawPath    string    // encoded path hint (see EscapedPath method)

        ForceQuery bool      // append a query ('?') even if RawQuery is empty

        RawQuery   string    // encoded query values, without '?'

        Fragment   string    // fragment for references, without '#'

}

URL的一般格式:[scheme:][//[userinfo@]host][/]path[?query][#fragment]



客户端通过URL的查询参数向服务器传递信息,而URL结构的RawQuery字段记录的就是客户端向服务器传递的查询参数字符串。如:http://www.example.com/post?id=1234&name=chen ,则RawQuery字段的值存储的就是id=1234&name=chen ,要想获取键值对格式的查询参数,要对RawQuery值进行语法分析,但是使用Request结构的Form字段,系统提供了解析RawQuery的方法,将解析的键值对信息会存储在Form字段中。下面会主要会对Request结构的Form字段、PostForm字段和MultipartForm字段进行讲解。

请求首部

http.Header类型拥有4中基本方法,这些方法根据给定的键执行添加、删除、获取和设置等操作。
[JavaScript] 纯文本查看 复制代码

import (

        "net/http"

        "fmt"

)



func headers(w http.ResponseWriter,r *http.Request)  {

        r.ParseForm()

        h := r.Header

        fmt.Println(r.Header.Get("Accept-Encoding"))  //gzip, deflate

        fmt.Println(r.Header["Accept-Encoding"])   //[gzip, deflate]

        fmt.Fprintln(w,h)

}



func main() {

        http.HandleFunc("/headers",headers)

        http.ListenAndServe(":8080",nil)

}

r.Header.Get("Accept-Encoding")是通过Header类型的Get方法获取的头信息,其返回的就是字符串形式的首部值,而r.Header["Accept-Encoding"]是以切片的形式返回的。

请求主体

请求和响应的主体都是由Request结构的Body字段表示,该字段是一个io.ReadCloser接口。
[JavaScript] 纯文本查看 复制代码

import (

        "net/http"

        "fmt"

)



func body(w http.ResponseWriter,r *http.Request)  {

        bys := make([]byte,r.ContentLength)

        r.Body.Read(bys)

        w.Write(bys)

}



func main() {

        http.HandleFunc("/body",body)

        http.ListenAndServe(":8080",nil)

}



通过ContentLength表示的是主体数据的字节长度,根据该长度创建字节切片,在通过Read方法将主体数据读取到字节切片中。因为GET请求不包含报文主体,所以使用的是POST表单请求。
Go语言提供了诸如FormValue和FormFile这种的方法来提取通过POST方法提交的表单,所以用户一般不需要自行读取主体中未经处理的表单,以下讲解FormValue和FormFile等方法。

Go与HTML表单

HTML表单的内容类型(Content-Type)决定了POST请求在发送键值对时将使用何种格式,其中,表单的enctype(也就是Content-Type)属性指定的值可以是application/x-www-form-urlencoded和multipart/form-data等。如果enctype属性的值设置为application/x-www-form-urlencoded,那么表单中的数据编码为一个连续的“长查询字符串”,这种编码和URL编码是一样的,如:id=1234&name=chen。如enctype属性的值设置为multipart/form-data,那么表单中的数据将被转换为一条MIME报文,表单中的每个键值对都构成了这条报文的一部分,并且每个键值对都带有它们各自的内容类型以及内容配置。以下是使用multipart/form-data编码对表单数据进行格式化的例子:

----------------------------780741602912379251409253
Content-Disposition: form-data; name="id"

123
----------------------------780741602912379251409253
Content-Disposition: form-data; name="name"

chen
----------------------------780741602912379251409253--


那么application/x-www-form-urlencoded和multipart/form-data两种编码应该如何选择呢,如果表单传送的简单的文本数据,那么使用URL编码格式更好,因为这种编码更为简单、高效,并且它所需的计算量要比另一种编码少,如果表单需要传送大量数据(如上传文件),那么使用multipart/form-data编码格式会更好一些。

Form字段

前面提到了如果直接获取请求体数据,需要自行进行语法分析,解析出键值对数据,而net/http库已经提供了一套用途相当广泛的函数,这些函数一般都能够满足用户对数据提取方面的需求,所以我们很少需要自行对表单数据进行语法分析。
通过调用Request结构提供的方法,用户可以将URL、主体又或者以上两者记录的数据提取到该结构的Form、PostForm和MultipartForm等字段当中。跟我们平常通过POST请求获取到的数据一样,存储在这些字段里面的数据也是以键值对形式表示的。使用Request结构的方法获取表单数据的一般步骤是:
(1)调用ParseForm()方法或者ParseMultipartForm()方法,对请求进行语法分析。
(2)根据步骤1调用的方法,访问相应的Form字段、PostForm字段或MultipartForm字段。
使用ParseForm()方法对表单进行语法分析的例子:

[JavaScript] 纯文本查看 复制代码
import (

        "net/http"

        "fmt"

)



func process(w http.ResponseWriter,r *http.Request)  {

        fmt.Println(r.Form)  //map[]

        r.ParseForm()

        fmt.Println(r.Form)  //map[id:[123] name:[chen hello world] hello:[world]]

        fmt.Fprint(w,r.Form)

}



func main() {

        http.HandleFunc("/process",process)

        http.ListenAndServe(":8080",nil)

}







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2