HTTP 協議簡介

HTTP (HyperText Transfer Protocol, 超文本傳輸協議)是互聯網上應用最爲普遍的一種網絡協議,它是基於 TCP應用層協議,簡單地說就是客戶端和服務器進行通訊的一種規則,它的模式很是簡單,就是客戶端發起請求,服務器響應請求,以下圖所示:javascript

HTTP 最先於 1991 年發佈,是 0.9 版,不過目前該版本已再也不用。HTTP 目前在使用的版本主要有:css

  • HTTP/1.0,於 1996 年 5 月發佈,引入了多種功能,至今仍在使用當中。
  • HTTP/1.1,於 1997 年 1 月發佈,持久鏈接被默認採用,是目前最流行的版本。
  • HTTP/2 ,於 2015 年 5 月發佈,引入了服務器推送等多種功能,是目前最新的版本。

HTTP 請求

HTTP 請求由三部分組成:html

  • 請求行:包含請求方法、請求地址和 HTTP 協議版本
  • 消息報頭:包含一系列的鍵值對
  • 請求正文(可選):注意和消息報頭之間有一個空行

如圖所示:java

下面是一個 HTTP GET 請求的例子:python

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複製代碼

上面的第一行就是一個請求行nginx

GET / HTTP/1.1複製代碼

其中,GET 是請求方法,表示從服務器獲取資源;/ 是一個請求地址;HTTP/1.1 代表 HTTP 的版本是 1.1。web

請求行後面的一系列鍵值對就是消息報頭shell

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複製代碼

其中:數據庫

  • Host 是請求報頭域,用於指定被請求資源的 Internet 主機和端口號,它一般從 HTTP URL 中提取出來;
  • Connection 表示鏈接狀態,keep-alive 表示該鏈接是持久鏈接(persistent connection),即 TCP 鏈接默認不關閉,能夠被多個請求複用,若是客戶端和服務器發現對方有一段時間沒有活動,就能夠主動關閉鏈接;
  • Cache-Control 用於指定緩存指令,它的值有 no-cache, no-store, max-age 等,max-age=秒表示資源在本地緩存多少秒;
  • User-Agent 用於標識請求者的一些信息,好比瀏覽器類型和版本,操做系統等;
  • Accept 用於指定客戶端但願接受哪些類型的信息,好比 text/html, image/gif 等;
  • Accept-Encoding 用於指定可接受的內容編碼;
  • Accept-Language 用於指定可接受的天然語言;
  • Cookie 用於維護狀態,可作用戶認證,服務器檢驗等,它是瀏覽器儲存在用戶電腦上的文本片斷;

HTTP 請求方法

HTTP 經過不一樣的請求方法以多種方式來操做指定的資源,經常使用的請求方法以下表:json

方法 描述
GET 從服務器獲取指定(請求地址)的資源的信息,它一般只用於讀取數據,就像數據庫查詢同樣,不會對資源進行修改。
POST 向指定資源提交數據(好比提交表單,上傳文件),請求服務器進行處理。數據被包含在請求正文中,這個請求可能會建立新的資源或更新現有的資源。
PUT 經過指定資源的惟一標識(在服務器上的具體存放位置),請求服務器建立或更新資源。
DELETE 請求服務器刪除指定資源。
HEAD 與 GET 方法相似,從服務器獲取資源信息,和 GET 方法不一樣的是,HEAD 不含有呈現數據,僅僅是 HTTP 頭信息。HEAD 的好處在於,使用這個方法能夠在沒必要傳輸所有內容的狀況下,就能夠得到資源的元信息(或元數據)。
OPTIONS 該方法可以使服務器傳回資源所支持的全部 HTTP 請求方法。

再議 POST 和 PUT

注意到,POST 和 PUT 均可用於建立或更新資源,然而,它們之間仍是有比較大的區別:

  • POST 所對應的 URI 並不是建立的資源自己,而是資源的接收者,資源自己的存放位置由服務器決定;而 PUT 所對應的 URI 是要建立或更新的資源自己,它指明瞭具體的存放位置

好比,往某個站點添加一篇文章,若是使用 POST 來建立資源,可相似這樣:

POST /articles HTTP/1.1

{
    "author": "ethan",
    "title": "hello world",
    "content": "hello world"
}複製代碼

在上面,POST 對應的 URI 是 /articles,它是資源的接收者,而非資源的標識,若是資源被成功建立,服務器能夠返回 201 Created 狀態以及新建資源的位置,好比:

HTTP/1.1 201 Created
Location: /articles/abcdef123複製代碼

咱們若是知道新建資源的標識符,能夠使用 PUT 來建立資源,好比:

PUT /articles/abcdef234 HTTP/1.1

{
    "author": "peter",
    "title": "hello world",
    "content": "hello world"
}複製代碼

在上面,PUT 對應的 URI 是 /articles/abcdef234,它指明瞭資源的存放位置,若是資源被成功建立,服務器能夠返回 201 Created 狀態以及新建資源的位置,好比:

HTTP/1.1 201 Created
Location: /articles/abcdef234複製代碼
  • 使用 PUT 更新某一資源,須要更新資源的所有屬性;而使用 POST,能夠更新所有或一部分值

好比使用 PUT 更新地址爲 /articles/abcdef234 的文章的標題,咱們須要發送全部值:

PUT /articles/abcdef234 HTTP/1.1

{
    "author": "peter",
    "title": "hello python",
    "content": "hello world"
}複製代碼

而使用 POST,能夠更新某個域的值:

POST /articles/abcdef234 HTTP/1.1

{
    "title": "hello python"
}複製代碼
  • POST 是不冪等的,PUT 是冪等的,這是一個很重要的區別

HTTP 方法的冪等性是指一次和屢次請求某一個資源應該具備一樣的反作用,注意這裏是反作用,而不是返回結果。

GET 方法用於獲取資源,不會改變資源的狀態,不論調用一次仍是屢次都沒有反作用,所以它是冪等的;DELETE 方法用於刪除資源,有反作用,但調用一次或屢次都是刪除同個資源,產生的反作用是相同的,所以也是冪等的;POST 是不冪等的,由於兩次相同的 POST 請求會在服務器建立兩份資源,它們具備不一樣的 URI;PUT 是冪等的,對同一 URI 進行屢次 PUT 的反作用和一次 PUT 是相同的。

HTTP 響應

HTTP 響應與 HTTP 請求類似,由三部分組成:

  • 狀態行:包含 HTTP 協議版本、狀態碼和狀態描述,以空格分隔
  • 響應頭:即消息報頭,包含一系列的鍵值對
  • 響應正文:返回內容,注意和響應頭之間有一個空行

如圖所示:

下面是一個 HTTP GET 請求的響應結果:

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"
}複製代碼

上面的第一行就是一個狀態行

HTTP/1.1 200 OK複製代碼

其中,200 是狀態碼,表示客戶端請求成功,OK 是相應的狀態描述。

狀態碼是一個三位的數字,常見的狀態碼有如下幾類:

  • 1XX 消息 -- 請求已被服務接收,繼續處理
  • 2XX 成功 -- 請求已成功被服務器接收、理解、並接受
    • 200 OK
    • 201 Created 已建立
    • 202 Accepted 接收
    • 203 Non-Authoritative Information 非認證信息
    • 204 No Content 無內容
  • 3XX 重定向 -- 須要後續操做才能完成這一請求
    • 301 Moved Permanently 請求永久重定向
    • 302 Moved Temporarily 請求臨時重定向
    • 304 Not Modified 文件未修改,能夠直接使用緩存的文件
    • 305 Use Proxy 使用代理
  • 4XX 請求錯誤 -- 請求含有詞法錯誤或者沒法被執行
    • 400 Bad Request 因爲客戶端請求有語法錯誤,不能被服務器所理解
    • 401 Unauthorized 請求未經受權。這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用
    • 403 Forbidden 服務器收到請求,可是拒絕提供服務。服務器一般會在響應正文中給出不提供服務的緣由
    • 404 Not Found 請求的資源不存在,例如,輸入了錯誤的URL
  • 5XX 服務器錯誤 -- 服務器在處理某個正確請求時發生錯誤
    • 500 Internal Server Error 服務器發生不可預期的錯誤,致使沒法完成客戶端的請求
    • 503 Service Unavailable 服務器當前不可以處理客戶端的請求,在一段時間以後,服務器可能會恢復正常
    • 504 Gateway Time-out 網關超時

狀態行後面的一系列鍵值對就是消息報頭,即響應頭:

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複製代碼

其中:

  • Server 包含了服務器用來處理請求的軟件信息,跟請求報頭域 User-Agent 相對應;
  • Content-Type 用於指定發送給接收者(好比瀏覽器)的響應正文的媒體類型,好比 text/html, text/css, image/png, image/jpeg, video/mp4, application/pdf, application/json 等;
  • Content-Length 指明本次迴應的數據長度;

HTTP 特色

  • 客戶端/服務器模式
  • 簡單快速:客戶端向服務器請求服務時,經過傳送請求方法、請求地址和數據體(可選)便可
  • 靈活:容許傳輸任意類型的數據對象,經過 Content-Type 標識
  • 無狀態:對事物處理沒記憶能力

小結

  • HTTP 是在網絡上傳輸 HTML 的協議,用於瀏覽器和服務器的通訊,默認使用 80 端口。
  • URL 地址用於定位資源,HTTP 中的 GET, POST, PUT, DELETE 用於操做資源,好比查詢,增長,更新等。
  • GET, PUT, DELETE 是冪等的,POST 是不冪等的。
  • POST VS PUT
    • 使用 PUT 建立資源須要提供資源的惟一標識(具體存放位置),POST 不須要,POST 的數據存放位置由服務器本身決定
    • 使用 PUT 更新某一資源,須要更新資源的所有屬性;而使用 POST,能夠更新所有或一部分值
    • POST 是不冪等的,PUT 是冪等的,這是一個很重要的區別
  • GET 可提交的數據量受到 URL 長度的限制,HTTP 協議規範沒有對 URL 長度進行限制,這個限制是特定的瀏覽器及服務器對它的限制。
  • 理論上講,POST 是沒有大小限制的,HTTP 協議規範也沒有進行大小限制,出於安全考慮,服務器軟件在實現時會作必定限制。

本文由 funhacks 發表於我的博客,採用 Creative Commons BY-NC-ND 4.0(自由轉載-保持署名-非商用-禁止演繹)協議發佈。
非商業轉載請註明做者及出處。商業轉載請聯繫做者本人。
本文標題爲: HTTP 協議簡介
本文連接爲: funhacks.net/2017/03/01/…

參考資料

相關文章
相關標籤/搜索