1. 程式人生 > >Request請求和Response響應

Request請求和Response響應

請求頭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 教程