Go中处理请求

hanzkering · · 1499 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

## 1 概述 Go 语言 HTTP 服务器,在启动监听并处理接收的请求时,会将请求相关数据封装成 `http.Request` 对象,同时作为参数传递到请求处理器中。处理器函数的第二个参数就是对 `http.Request` 对象的一个引用,示例代码为: ```go func main() { // 设置 路由 http.HandleFunc("/", IndexAction)· // 开启监听 log.Fatal(http.ListenAndServe(":8888", nil)) } func IndexAction(w http.ResponseWriter, r *http.Request) { w.Write([]byte(`<h1 align="center">来自小韩说课的问候</h1>`)) } ``` <!-- more --> ## 2 `http.Request` 结构 ```go type Request struct { Method string // 请求方法,"" 默认为 GET URL *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 // 解析好的 form 数据,同时包含 URL 中的 QueryString,调用 ParseForm() 后生效 PostForm url.Values // 解析好的 POST、PUT、PATCH 的 form 数据,调用 ParseForm() 后生效 MultipartForm *multipart.Form // 解析好的 multipart form,包含上传文件 Trailer Header // 指定请求发送后的附加头信息 RemoteAddr string // 请求来源地址 RequestURI string // 请求行中未修改的请求URI,通常使用 URL 字段代替 TLS *tls.ConnectionState // TLS 状态信息对象 Cancel <-chan struct{} // 指示客户端请求可取消的闭包通道 Response *Response // 重定向到引发本次请求的响应对象 ctx context.Context // 服务器与客户端的上下文 } ``` ## 3 请求方式 ```go func IndexAction(w http.ResponseWriter, r *http.Request) { log.Print(r.Method) } // GET ``` ## 4 请求参数 通过 `URL.Query()` 方法可以获取查询字符串值 `URL.values` 对象,是一个映射结构。对象上的 `.Get(key string)` 方法获取 key 对应的第一个值。 ```go // http://localhost:8888/?name=Hank func IndexAction(w http.ResponseWriter, r *http.Request) { log.Print(r.URL.Query()) log.Print(r.URL.Query()["name"]) log.Print(r.URL.Query().Get("name")) } // map[name:[Hank]] // [Hank] // Hank ``` 除此之外,请求值对象 `URL.Values` 还支持: * `func (v Values) Set(key, value string)` 设置方法 * `func (v Values) Add(key, value string)` 添加值方法 * `func (v Values) Del(key string)` 删除值方法 * `func (v Values) Encode() string` URL编码 Values ## 5 请求头 请求对象的 `Header` 属性可以访问到请求头信息。是映射结构,提供了 `Get(key string)` 方法获取 key 对应的第一个值。 ```go // http://localhost:8888/ func IndexAction(w http.ResponseWriter, r *http.Request) { log.Print(r.Header) log.Print(r.Header["User-Agent"]) log.Print(r.Header.Get("User-Agent")) } // map[User-Agent:[Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36] Accept:[text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8] Accept-Encoding:[gzip, deflate, br] Accept-Language:[zh-CN,zh;q=0.9,en;q=0.8] Connection:[keep-alive] Cache-Control:[max-age=0] Upgrade-Insecure-Requests:[1]] // [Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36] // Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 ``` 除此之外,`Header` 对象还支持: * `func (h Header) Set(key, value string)` 设置头 * `func (h Header) Add(key, value string)` 添加头 * `func (h Header) Del(key string)` 删除头 * `func (h Header) Write(w io.Writer) error` // 使用线模式(in wire format)写头信息 ## 6 请求 URL `Request.URL` 引用的是 `url.URL` 结构体类型,利用该对象可以获取 URL 相关信息。其定义结构为: ```go type URL struct { Scheme string // 协议 Opaque string // 编码数据 User *Userinfo // username 和 password 信息 Host string // 主机,格式为 host:port Path string // 路径(相对路径会省略前导斜钱) RawPath string // 编码 path (see EscapedPath method) ForceQuery bool // 追加查询 ('?') 即使 RawQuery 为空 RawQuery string // 编码查询字符串, 不包括 '?' Fragment string // 引用片段, 不包括 '#' } ``` 典型的URL格式为: `scheme://[userinfo@]host/path[?query][#fragment]`。 注意,服务器端程序会获取 URI 信息而客户端信息会获取 URL 信息。 示例: ```go // http://localhost:8888/path/to/script.html func IndexAction(w http.ResponseWriter, r *http.Request) { log.Print(r.URL.Path) } // /path/to/script.html ``` 完! 原文出自:[小韩说课](http://www.hellokang.net/go/go-http-request/) 微信关注:小韩说课 ![小韩说课](http://www.hellokang.net/images/wechat_subscription.jpg)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1499 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传