HTTP (HyperText Transfer Protocol, 超文本傳輸協(xié)議)是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議,它是基于 TCP 的應(yīng)用層協(xié)議,簡單地說就是客戶端和服務(wù)器進行通信的一種規(guī)則,它的模式非常簡單,就是客戶端發(fā)起請求,服務(wù)器響應(yīng)請求,如下圖所示:

HTTP 最早于 1991 年發(fā)布,是 0.9 版,不過目前該版本已不再用。HTTP 目前在使用的版本主要有:
HTTP 請求由三部分組成:
如圖所示:

下面是一個 HTTP GET 請求的例子:
GET / HTTP/1.1
Host: httpbin.org
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
Cookie: _ga=GA1.2.475070272.1480418329; _gat=1
上面的第一行就是一個請求行:
GET / HTTP/1.1
其中,GET 是請求方法,表示從服務(wù)器獲取資源;/ 是一個請求地址;HTTP/1.1 表明 HTTP 的版本是 1.1。
請求行后面的一系列鍵值對就是消息報頭:
Host: httpbin.org
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4
Cookie: _ga=GA1.2.475034215.1480418329; _gat=1
其中:
max-age=秒表示資源在本地緩存多少秒;HTTP 通過不同的請求方法以多種方式來操作指定的資源,常用的請求方法如下表:
| 方法 | 描述 |
|---|---|
| GET | 從服務(wù)器獲取指定(請求地址)的資源的信息,它通常只用于讀取數(shù)據(jù),就像數(shù)據(jù)庫查詢一樣,不會對資源進行修改。 |
| POST | 向指定資源提交數(shù)據(jù)(比如提交表單,上傳文件),請求服務(wù)器進行處理。數(shù)據(jù)被包含在請求正文中,這個請求可能會創(chuàng)建新的資源或更新現(xiàn)有的資源。 |
| PUT | 通過指定資源的唯一標識(在服務(wù)器上的具體存放位置),請求服務(wù)器創(chuàng)建或更新資源。 |
| DELETE | 請求服務(wù)器刪除指定資源。 |
| HEAD | 與 GET 方法類似,從服務(wù)器獲取資源信息,和 GET 方法不同的是,HEAD 不含有呈現(xiàn)數(shù)據(jù),僅僅是 HTTP 頭信息。HEAD 的好處在于,使用這個方法可以在不必傳輸全部內(nèi)容的情況下,就可以獲得資源的元信息(或元數(shù)據(jù))。 |
| OPTIONS | 該方法可使服務(wù)器傳回資源所支持的所有 HTTP 請求方法。 |
HTTP 響應(yīng)與 HTTP 請求相似,由三部分組成:
如圖所示:

下面是一個 HTTP GET 請求的響應(yīng)結(jié)果:
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 29 Nov 2016 13:08:38 GMT
Content-Type: application/json
Content-Length: 203
Connection: close
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
{
"args": {},
"headers": {
"Host": "httpbin.org",
"User-Agent": "Paw/2.3.1 (Macintosh; OS X/10.11.3) GCDHTTPRequest"
},
"origin": "13.75.42.240",
"url": "https://httpbin.org/get"
}
上面的第一行就是一個狀態(tài)行:
HTTP/1.1 200 OK
其中,200 是狀態(tài)碼,表示客戶端請求成功,OK 是相應(yīng)的狀態(tài)描述。
狀態(tài)碼是一個三位的數(shù)字,常見的狀態(tài)碼有以下幾類:
狀態(tài)行后面的一系列鍵值對就是消息報頭,即響應(yīng)頭:
Server: nginx
Date: Tue, 29 Nov 2016 13:08:38 GMT
Content-Type: application/json
Content-Length: 203
Connection: close
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
其中:
注意到,POST 和 PUT 都可用于創(chuàng)建或更新資源,然而,它們之間還是有比較大的區(qū)別:
比如,往某個站點添加一篇文章,如果使用 POST 來創(chuàng)建資源,可類似這樣:
POST /articles HTTP/1.1
{
"author": "ethan",
"title": "hello world",
"content": "hello world"
}
在上面,POST 對應(yīng)的 URI 是 /articles,它是資源的接收者,而非資源的標識,如果資源被成功創(chuàng)建,服務(wù)器可以返回 201 Created 狀態(tài)以及新建資源的位置,比如:
HTTP/1.1 201 Created
Location: /articles/abcdef123
我們?nèi)绻佬陆ㄙY源的標識符,可以使用 PUT 來創(chuàng)建資源,比如:
PUT /articles/abcdef234 HTTP/1.1
{
"author": "peter",
"title": "hello world",
"content": "hello world"
}
在上面,PUT 對應(yīng)的 URI 是 /articles/abcdef234,它指明了資源的存放位置,如果資源被成功創(chuàng)建,服務(wù)器可以返回 201 Created 狀態(tài)以及新建資源的位置,比如:
HTTP/1.1 201 Created
Location: /articles/abcdef234
比如使用 PUT 更新地址為 /articles/abcdef234 的文章的標題,我們需要發(fā)送所有值:
PUT /articles/abcdef234 HTTP/1.1
{
"author": "peter",
"title": "hello python",
"content": "hello world"
}
而使用 POST,可以更新某個域的值:
POST /articles/abcdef234 HTTP/1.1
{
"title": "hello python"
}
HTTP 方法的冪等性是指一次和多次請求某一個資源應(yīng)該具有同樣的副作用,注意這里是副作用,而不是返回結(jié)果。
GET 方法用于獲取資源,不會改變資源的狀態(tài),不論調(diào)用一次還是多次都沒有副作用,因此它是冪等的;DELETE 方法用于刪除資源,有副作用,但調(diào)用一次或多次都是刪除同個資源,產(chǎn)生的副作用是相同的,因此也是冪等的;POST 是不冪等的,因為兩次相同的 POST 請求會在服務(wù)器創(chuàng)建兩份資源,它們具有不同的 URI;PUT 是冪等的,對同一 URI 進行多次 PUT 的副作用和一次 PUT 是相同的。