3.1. Request对象
net/http.Request
net/http库的Request对象是一个http请求的信息载体,保存固定结构而不需要是一个接口,Request是net/http库客户端和服务端公用的对象,所以部分属性有时不需要。
Request对象定义:
type Request struct {
Method string
RequestURI string
URL *url.URL
Proto string // "HTTP/1.0"
ProtoMajor int // 1
ProtoMinor int // 0
Header Header
Host string
Body io.ReadCloser
GetBody func() (io.ReadCloser, error) // Go 1.8
ContentLength int64
TransferEncoding []string
Trailer Header
Form url.Values
PostForm url.Values // Go 1.1
MultipartForm *multipart.Form
RemoteAddr string
TLS *tls.ConnectionState
Cancel <-chan struct{} // Go 1.5
Close bool
Response *Response // Go 1.7
}
各属性说明:
属性 | 类型 | C/S | 解释 |
---|---|---|---|
Method | string | 请求方法 | |
RequestURI | string | S | 请求行uri,是未转义前的原生数据 |
URL | *url.URL | 请求行uri解析的数据 | |
Proto | string | http版本,例如HTTP/1.0 HTTP/1.1 HTTP/2.0 | |
ProtoMajor | int | 主版本号1 2 | |
ProtoMinor | int | 次版本号0 1 | |
Header | Header | 请求中的header,除host和Trailer以外 | |
Host | string | 请求的host,如果HTTP/1.0则未空 | |
Body | io.ReadCloser | 请求Body是一个rc接口,可以读取body, | |
GetBody | func() (io.ReadCloser, error) | C | 如果客户端遇到请求重定向,就需要使用GetBody获得一个Body副本重新发送。 |
ContentLength | int64 | 记录请求的长度HTTP/1.1,需要长度来区分包的边界。未知值就是-1 | |
TransferEncoding | []string | 定义传输编码,例如分段传输 | |
Trailer | Header | Trailer允许先发送Body再发送Header,Trailer需要再分段传输下使用。 | |
Form | url.Values | S | url参数和form body数据 |
PostForm | url.Values | S | form body数据 |
MultipartForm | *multipart.Form | S | Form表单的完整数据 |
RemoteAddr | string | S | 客户端连接的地址 |
TLS | *tls.ConnectionState | S | tls握手的状态,可以判断是否为https |
Close | bool | S | 返回响应后就为true |
Cancel | <-chan struct{} | C | |
Response | *Response | C | 客户端重定向后响应对象 |
按照类型大致总结下:
- Method到Body、GetBody都是基本的请求信息,请求行、Header、Body的数据。
- ContentLength、TransferEncoding、Trailer和HTTP/1.1长连接传输实现有关,ContentLength是记录body长度,TransferEncoding是分段记录长度,Trailer在分段传输是最后追加header。
- Form、PostForm、MultipartForm是请求的数据,包含url参数和两种表单body解析的数据的保存。
- MultipartForm、TLS等记录一些传输信息。
基础方法
Clone方法深拷贝一个Requeest对象;Context方法返回当前请求的环境上下文;WithContext设置环境上下文,返回一个新的复制对象。
func (r *Request) Clone(ctx context.Context) *Request
func (r *Request) Context() context.Context
func (r *Request) WithContext(ctx context.Context) *Request
客户端方法
SetBasicAuth方法就是设置Authorization header值为用户名;AddCookie方法添加一个Cookie header;Write方法和WriteProxy方法将请求对象按照http协议写入。
func (r *Request) SetBasicAuth(username, pass
func (r *Request) AddCookie(c *Cookie)
func (r *Request) Write(w io.Writer) error
func (r *Request) WriteProxy(w io.Writer) errorword string)
服务端基本方法
Referer、UserAgent方法分别返回Referer和User-Agent两个header的值;BasicAuth方法返回Authorization header值解码后的用户名,解码失败ok为false,Cookies方法解析全部Cookie Header返回多个Cookie数据;Cookie方法就从Cookies的数据中遍历获得对应的name的数据;ProtoAtLeast方法检测http版本号。
func (r *Request) Referer() string
func (r *Request) UserAgent() string
func (r *Request) BasicAuth() (username, password string, ok bool)
func (r *Request) Cookies() []*Cookie
func (r *Request) Cookie(name string) (*Cookie, error)
func (r *Request) ProtoAtLeast(major, minor int) bool
服务端数据获取
http.Request中Form、PostForm、MultipartForm三个对象和表单数据保存相关。
type Request struct {
...
Form url.Values
PostForm url.Values // Go 1.1
MultipartForm *multipart.Form
}
Form保存url请求参数解析出来的数据。
如果是body内容是url表单,解析的数据在PostForm,同时复制一份保存到Form中。
如果是body内容是form表单,解析的数据在MultipartForm,包含Form的Value和File数据,同时复制一份Value保存到Form和PostForm中。
// from godoc
type Request
func (r *Request) ParseForm() error
func (r *Request) ParseMultipartForm(maxMemory int64) error
func (r *Request) FormValue(key string) string
func (r *Request) PostFormValue(key string) string
func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error)
func (r *Request) MultipartReader() (*multipart.Reader, error)
Form、PostForm、MultipartForm三个对象默认都是nil,需要调用相关函数后才会触发解析并保存数据,相关一共存在6个方法,触发解析后可以直接使用请求的Form、PostForm、MultipartForm三个对象。如果直接使用Form无法获取到数据,就是没有触发数据解析。
ParseForm方法:如果是请求方法为POST、PUT、PATCH且body内容是url表单会解析body保存到PostForm和Form中,然后再解析url请求参数,该方法无法解析form表单。
ParseMultipartForm方法:先调用ParseForm方法一遍,如果不返回err,然后使用body解析成form表单数据保存在MultipartForm中,再复制Form的Value数据到Form和PostForm中,默认最大body是32<<20byte即32MB。
FormValue方法:先调用ParseMultipartForm方法,然后从Form返回数据。
PostFormValue方法:先调用ParseMultipartForm方法,然后从PostForm返回数据,与FormValue方法的区别忽略url请求参数。
FormFile方法:先调用ParseMultipartForm方法,然后从FormFile.File返回文件。
MultipartReader方法:封装请求body成*multipart.Reader
,然后可以调用方法解析出Form对象,该行为需要调用Form.RemoveAll方法释放临时文件。
具体实现参考源码
反馈和交流请加群组:QQ群373278915。