请求头Request和响应头Response都是个map,map的key为string(字符串),map的value为数组,为什么value是个数组呢,因为有些key-value(也就是键值对)可能有多个value,比如cookie,大部分网页都有cookie,而且大多数网页都有很多个cookie,而cookie就存在Request请求头和Response响应头里面,请求头和响应头里面可以存很多内容。
Response(响应)
当用户访问一个网址时,他会看到一个页面,这个页面上所呈现的内容,也就是用户直接看到的内容,是Response.body(响应体)。但是,服务器返回的内容除了【响应体】,还包括【响应头】和【响应首行】,不过【响应头】和【响应首行】用户是看不到的,必须使用一些抓取工具才能看到。
【响应首行】主要包括
//状态
Status string // e.g. "200 OK"
//状态码
StatusCode int // e.g. 200
//HTTP协议版本
Proto string // e.g. "HTTP/1.0"
//协议主版本号
ProtoMajor int // e.g. 1
//协议副版本号
ProtoMinor int // e.g. 0
而【响应头】因为网站的开发者可以自行设置,所以内容就比较多,下面来模拟访问一下百度首页,看一下返回的响应头里面都有什么,
package main
import (
"fmt"
"net/http"
)
func main() {
url := "https://www.baidu.com"
//创建一个模拟客户端
client := http.Client{}
//创建一个request(创建一个请求)
request, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println(err)
}
//用模拟客户端去执行请求,访问百度首页,获得response(获得响应)
response, err := client.Do(request)
if err != nil {
fmt.Println(err)
}
fmt.Println("------------response-key-value")
for key, value := range response.Header {
fmt.Println(key, value)
}
fmt.Println("-------------response-header-key--------------")
for key, _ := range response.Header {
fmt.Println(key)
}
fmt.Println("-------------response-header-value--------------")
for _, value := range response.Header {
fmt.Println(value)
}
}
运行结果
------------response-key-value
Pragma [no-cache]
Server [BWS/1.1]
Cache-Control [no-cache]
X-Ua-Compatible [IE=Edge,chrome=1]
Strict-Transport-Security [max-age=0]
Etag ["5c188dd0-e3"]
Set-Cookie [BD_NOT_HTTPS=1; path=/; Max-Age=300 BIDUPSID=A964CAF5FF1C8AC9B485A21EC5A5DD01; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com PSTM=1545184031; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com]
Accept-Ranges [bytes]
Content-Length [227]
Content-Type [text/html]
Date [Wed, 19 Dec 2018 01:47:11 GMT]
Last-Modified [Tue, 18 Dec 2018 06:04:00 GMT]
P3p [CP=" OTI DSP COR IVA OUR IND COM "]
Connection [Keep-Alive]
-------------response-header-key--------------
Etag
Set-Cookie
Accept-Ranges
Content-Length
Content-Type
Date
Last-Modified
P3p
Connection
Pragma
Server
Cache-Control
X-Ua-Compatible
Strict-Transport-Security
-------------response-header-value--------------
[text/html]
[Wed, 19 Dec 2018 01:47:11 GMT]
[Tue, 18 Dec 2018 06:04:00 GMT]
[CP=" OTI DSP COR IVA OUR IND COM "]
[Keep-Alive]
[227]
[BWS/1.1]
[no-cache]
[no-cache]
[max-age=0]
[IE=Edge,chrome=1]
[BD_NOT_HTTPS=1; path=/; Max-Age=300 BIDUPSID=A964CAF5FF1C8AC9B485A21EC5A5DD01; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com PSTM=1545184031; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com]
[bytes]
["5c188dd0-e3"]
因为响应头是网站开发者根据需要来自行设置的,所以访问不同的网站、不同的网址,得到的响应头都是不一样的,比如从上面我们可以看出,访问百度首页,得到的响应头里面包括这些信息,可以看到百度首页设置了好多个cookie。
Etag
Set-Cookie
Accept-Ranges
Content-Length
Content-Type
Date
Last-Modified
P3p
Connection
Pragma
Server
Cache-Control
X-Ua-Compatible
Strict-Transport-Security
这些信息中有些是所有网站的响应信息中都有的,比如
Connection :连接的方式,Keep-Alive表示长连接(即连接保持一段时间)。
Server:响应的服务类型和版本。
Content-Type:该value通常有多个内容,包括响应内容的文本类型,以及采用的字符编码等。
Content-Length:响应内容的长度。
Cache-Control:缓存控制,即是否包含缓存。
Set-Cookie:如果网站设置了cookie,就有该项。
Date:服务器返回响应的具体时间,用的是GMT格林威治标准时间(和UTC世界协调时间是一样)。
Request请求
模拟请求百度首页
package main
import (
"fmt"
"net/http"
)
func main() {
url := "https://www.baidu.com"
request, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println(err)
}
fmt.Println(request)
fmt.Println(request.Header)
fmt.Println(request.Body)
}
运行结果
&{GET https://www.baidu.com HTTP/1.1 1 1 map[] <nil> <nil> 0 [] false www.baidu.com map[] map[] <nil> map[] <nil> <nil> <nil> <nil>}
map[]
<nil>
第一行打的是发起一个请求之后,请求中的内容,请求中包括【请求首行】、【请求头】、【请求体】,不过【请求头】和【请求体】均为空,里面什么内容也没有。
这里的【请求首行】中的信息包括
//请求方法,
Method string
//请求的网址
URL *url.URL
//HTTP协议版本号
Proto string // "HTTP/1.0"
//协议主版本号
ProtoMajor int // 1
//协议副版本号
ProtoMinor int // 0
【请求头】为空是因为请求头和响应头一样,都是可以设置的,而这里一个也没有设置,所以为空,而如果是用浏览器访问百度首页,那请求头中的内容全都由浏览器替我们设置了,一般的,用浏览访问某网站,请求头中会包含这些内容,
Connection
User-Agent
Accept-Encoding
Accept-Language
Upgrade-Insecure-Requests
Accept
Referer
Cache-Control
Accept :浏览器支持的MIME类型。
Accept-Language :浏览器支持的语言环境。
User-Agent :浏览器的类型和OS的类型。
Accept-Encoding :浏览器支持的数据压缩格式,有时候服务器给浏览器发送的东西很大,这时候服务器就要考虑当数据被压缩后,浏览器能不能给解压出来,那么这个请求头就是浏览器告诉服务器它能够解压的格式。
Host :浏览器请求的主机名和端口号,虽然后面没有显示端口号,但是这个端口号是80,它是http协议默认的端口号。
Connection :连接的方式,Keep-Alive表示连接一会。
Cookie :如果网站设置了cookie,那么首次访问后,浏览器会将cookie保存,在下次访问时,带上cookie去访问。
如果客户端与服务器建立的是websocket连接,那么请求头中会通常包含下面这些信息
Pragma
Cache-Control
Upgrade
Origin
User-Agent
Accept-Encoding
Sec-Websocket-Version
Accept-Language
Sec-Websocket-Key
Sec-Websocket-Extensions
Connection
具体如下
Pragma [no-cache]
Origin [http://localhost:8080]
Sec-Websocket-Key [RxEiqYDTd0qVdBQNo9/uHg==]
Sec-Websocket-Extensions [permessage-deflate; client_max_window_bits]
User-Agent [Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/525.16 (KHTML, like Gecko) Chrome/67.2.3266.89 Safari/525.16]
Accept-Encoding [gzip, deflate, br]
Accept-Language [zh-CN,zh;q=0.9,en;q=0.8]
Connection [Upgrade]
Cache-Control [no-cache]
Upgrade [websocket]
Sec-Websocket-Version [13]
其中一些字段的意思
Upgrade: websocket和Connection: Upgrade表示这个连接将要被转换为WebSocket连接;
Sec-WebSocket-Key:是一个长度为24的字符串,用于标识这个连接,并非用于加密数据;
Sec-WebSocket-Version指定了WebSocket的协议版本。
参考文献
Golang中net/http包使用方法之http.Response
http请求,get请求和post请求体以及响应体
廖雪峰WebSocket
阮一峰WebSocket 教程