一、什麼是HTTP?

       超文字傳輸協議(英文:HyperText Transfer Protocol,縮寫:HTTP)是網際網路上應用最為廣泛的一種網路協議。設計HTTP最初的目的是為了提供一種釋出和接收HTML頁面的方法。通過HTTP或者HTTPS協議請求的資源由統一資源識別符號(Uniform Resource Identifiers,URI)來標識。

HTTP的發展是全球資訊網協會(World Wide Web Consortium)和Internet工作小組(Internet Engineering Task Force)合作的結果,(他們)最終釋出了一系列的RFC,其中最著名的RFC 2616,定義了HTTP協議中現今廣泛使用的一個版本—HTTP 1.1。

二、協議概述

       HTTP協議(HyperText Transfer Protocol,超文字轉移協議)是用於從WWW伺服器傳輸超文字到本地瀏覽器的傳送協議。它可以使瀏覽器更加高效,使網路傳輸減少。它不僅保證計算機正確快速地傳輸超文字文件,還確定傳輸文件中的哪一部分,以及哪部分內容首先顯示(如文字先於圖形)等

HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端伺服器模型。HTTP是一個無狀態的協議。

       通常,一次Web請求的基本過程:

       建立連線→接收請求處理請求訪問資源構建響應傳送響應記錄日誌

由HTTP客戶端發起一個請求,建立一個到伺服器指定埠(預設是80埠)的TCP連線。HTTP伺服器則在那個埠監聽客戶端的請求。一旦收到請 求,伺服器會向客戶端返回一個狀態,比如”HTTP/1.1 200 OK”,以及返回的內容,如請求的檔案、錯誤訊息、或者其它資訊。


HTTP協議的主要特點可概括如下:

1)支援客戶/伺服器模式。支援基本認證和安全認證。

2)簡單快速:客戶向伺服器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與伺服器聯絡的型別不同。由於HTTP協議簡單,使得HTTP伺服器的程式規模小,因而通訊速度很快。

3)無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。

三、HTTP協議版本
        超文字傳輸協議已經演化出了很多版本,它們中的大部分都是向下相容的。在RFC 2145中描述了HTTP版本號的用法。客戶端在請求的開始告訴伺服器它採用的協議版本號,而後者則在響應中採用相同或者更早的協議版本。

HTTP/0.9

       誕生於1991,僅用於傳輸html文件,已過時。只接受GET一種請求方法,沒有在通訊中指定版本號,且不支援請求頭。由於該版本不支援POST方法,因此客戶端無法向伺服器傳遞太多資訊

HTTP/1.0
       這是第一個在通訊中指定版本號的HTTP協議版本,至今仍被廣泛採用,特別是在代理伺服器中。支援多媒體資料的處理,keep-alive(保持連線),有快取功能
HTTP/1.1
       當前版本。持久連線被預設採用,並能很好地配合代理伺服器工作。還支援以管道方式在同時傳送多個請求,以便降低線路負載,提高傳輸速度。更多的請求方法,更精細的快取控制,持久連線

HTTP/1.1相較於HTTP/1.0協議的區別主要體現在:

·快取處理

·頻寬優化及網路連線的使用

·錯誤通知的管理

·訊息在網路中的傳送

·網際網路地址的維護

·安全性及完整性

MIME: Multipurpose Internet Mail Extension

base64: 
將二進位制資料編碼成文字傳送,並能夠讓接收方還原回原來的格式;


四、HTTP報文:
HTTP
事務:一次請求以及與其對應的響應的過程

HTTP請求:request
HTTP
請求報文
報文格式:

<method> <request-URL> <version>

<headers>


<entity-body>

HTTP響應:response
HTTP響應報文

報文格式:

<version> <status> <reason-phrase>

<headers>


<entity-body> 

其中:

<method>: 請求方法,希望伺服器端執行的動作,如GET、HEAD、POST等

<request-url>: 請求的資源,可以是相對路徑,也是完整的URL

<version>:協議版本,格式HTTP/<major>.<minor>,如http/1.0

<headers>:HTTP首部

<status>: 狀態碼

<reason-phrase>:原因短語,數字狀態碼易讀資訊

<entity-body>: 主體部分


求方法<method>

HTTP/1.1協議中共定義了八種方法(也叫“動作”)來以不同方式操作指定的資源:

GET:向指定的資源發出“顯示”請求;需要伺服器傳送;

HEAD:跟GET相似,但其不需要服務傳送資源而僅傳回響應首部

POST:向指定資源提交資料,支援HTML表單提交,表單中有使用者填入的資料,這些資料會傳送到伺服器端,由伺服器儲存至某位置(例如傳送處理程式)。

PUT與GET相反,向服務寫入文件;例如釋出系統

DELETE請求伺服器刪除Request-URI所標識的資源。

OPTIONS探測伺服器端對某資源所支援的請求方法

TRACE回顯伺服器收到的請求,主要用於測試或診斷。

CONNECTHTTP/1.1協議中預留給能夠將連線改為管道方式的代理伺服器。通常用於SSL加密伺服器的連結(經由非加密的HTTP代理伺服器)。

方法名稱是區分大小寫的。當某個請求所針對的資源不支援對應的請求方法的時候,伺服器應當返回狀態碼405(Method Not Allowed),當伺服器不認識或者不支援對應的請求方法的時候,應當返回狀態碼501(Not Implemented)。

HTTP伺服器至少應該實現GET和HEAD方法,其他方法都是可選的。當然,所有的方法支援的實現都應當符合下述的方法各自的語義定義。此外,除了上述方法,特定的HTTP伺服器還能夠擴充套件自定義的方法。例如:

PATCH(由RFC5789指定的方法):用於將區域性修改應用到資源。

除了以上八種方法外還有其他擴充套件方法:LOCK、MKCOL、COPY、MOVE


HTTP狀態碼<status>:   

狀態碼

狀態碼英文名稱

中文描述

1XX資訊性狀態碼

100

Continue

繼續。客戶端應繼續其請求

101

Switching Protocols

切換協議。伺服器根據客戶端的請求切換協議。只能切換到更高階的協議,例如,切換到HTTP的新版本協議

2xx:成功狀態碼

200

OK

請求成功。一般用於GET與POST請求

201

Created

已建立。成功請求並建立了新的資源

202

Accepted

已接受。已經接受請求,但未處理完成

203

Non-Authoritative Information

非授權資訊。請求成功。但返回的meta資訊不在原始的伺服器,而是一個副本

204

No Content

無內容。伺服器成功處理,但未返回內容。在未更新網頁的情況下,可確保瀏覽器繼續顯示當前文件

205

Reset Content

重置內容。伺服器處理成功,使用者終端(例如:瀏覽器)應重置文件檢視。可通過此返回碼清除瀏覽器的表單域

206

Partial Content

部分內容。伺服器成功處理了部分GET請求

3XX:重定向狀態碼

300

Multiple Choices

多種選擇。請求的資源可包括多個位置,相應可返回一個資源特徵與地址的列表用於使用者終端(例如:瀏覽器)選擇

301

Moved Permanently

永久移動。請求的資源已被永久的移動到新URI,返回資訊會包括新的URI,瀏覽器會自動定向到新URI。今後任何新的請求都應使用新的URI代替

302

Found

臨時移動。與301類似。但資源只是臨時被移動。客戶端應繼續使用原有URI

303

See Other

檢視其它地址。與301類似。使用GET和POST請求檢視

304

Not Modified

未修改。所請求的資源未修改,伺服器返回此狀態碼時,不會返回任何資源。客戶端通常會快取訪問過的資源,通過提供一個頭資訊指出客戶端希望只返回在指定日期之後修改的資源

305

Use Proxy

使用代理。所請求的資源必須通過代理訪問

306

Unused

已經被廢棄的HTTP狀態碼

307

Temporary Redirect

臨時重定向。與302類似。使用GET請求重定向

4XX:客戶端類的錯誤

400

Bad Request

客戶端請求的語法錯誤,伺服器無法理解

401

Unauthorized

請求要求使用者的身份認證

402

Payment Required

保留,將來使用

403

Forbidden

伺服器理解請求客戶端的請求,但是拒絕執行此請求

404

Not Found

伺服器無法根據客戶端的請求找到資源(網頁)。通過此程式碼,網站設計人員可設定”您所請求的資源無法找到”的個性頁面

405

Method Not Allowed

客戶端請求中的方法被禁止

406

Not Acceptable

伺服器無法根據客戶端請求的內容特性完成請求

407

Proxy Authentication Required

請求要求代理的身份認證,與401類似,但請求者應當使用代理進行授權

408

Request Time-out

伺服器等待客戶端傳送的請求時間過長,超時

409

Conflict

伺服器完成客戶端的PUT請求時可能返回此程式碼,伺服器處理請求時發生了衝突

410

Gone

客戶端請求的資源已經不存在。410不同於404,如果資源以前有現在被永久刪除了可使用410程式碼,網站設計人員可通過301程式碼指定資源的新位置

411

Length Required

伺服器無法處理客戶端傳送的不帶Content-Length的請求資訊

412

Precondition Failed

客戶端請求資訊的先決條件錯誤

413

Request Entity Too Large

由於請求的實體過大,伺服器無法處理,因此拒絕請求。為防止客戶端的連續請求,伺服器可能會關閉連線。如果只是伺服器暫時無法處理,則會包含一個Retry-After的響應資訊

414

Request-URI Too Large

請求的URI過長(URI通常為網址),伺服器無法處理

415

Unsupported Media Type

伺服器無法處理請求附帶的媒體格式

416

Requested range not satisfiable

客戶端請求的範圍無效

417

Expectation Failed

伺服器無法滿足Expect的請求頭資訊

5XX:伺服器類的錯誤

500

Internal Server Error

伺服器內部錯誤,無法完成請求

501

Not Implemented

伺服器不支援請求的功能,無法完成請求

502

Bad Gateway

充當閘道器或代理的伺服器,從遠端伺服器接收到了一個無效的請求

503

Service Unavailable

由於超載或系統維護,伺服器暫時的無法處理客戶端的請求。延時的長度可包含在伺服器的Retry-After頭資訊中

504

Gateway Time-out

充當閘道器或代理的伺服器,未及時從遠端伺服器獲取請求

505

HTTP Version not supported

伺服器不支援請求的HTTP協議的版本,無法完成處理

HTTP首部:<headers>:

               Name: Value
如:Content-type: images/gif

分為以下幾類:

通用首部:請求和響應都可以使用的;

請求首部:

響應首部:

實體首部:用於指定實體屬性

擴充套件首部:非標準首部,可能是由程式開發者建立的,例如X-Forward-For

通用首部:

     Connection:定義C/S之間關於請求/響應的有關選項

          對於http/1.0, Connection: keep-alive

     Via: 顯示了報文經過的中間節點

     Cache-Control: 快取指示

     Pragma


請求首部:

      Client-IP:

      Host: 請求的主機名和埠號,虛擬主機環境下用於不同的虛擬主機

      Referer:指明瞭請求當前資源的原始資源的URL

      User-Agent: 使用者代理,使用什麼工具發出的請求


       Accept首部:使用者標明客戶自己更傾向於支援的能力

           Accept: 指明伺服器能傳送的媒體型別

           Accept-Charset: 支援使用的字符集

           Accept-Encoding: 支援使用的編碼方式

           Accept-Language: 支援使用語言


        條件請求首部:

            Expect: 

            If-Modified-Since: 是否在指定時間以來修改過此資源

            If-None-Match


       跟安全相關的請求首部:

            Authorization: 客戶端提交給服務端的認證資料,如帳號和密碼

            Cookie: 客戶端傳送給伺服器端身份標識

            Cookie2


響應首部:

      Age: 

      Server: 向客戶端標明伺服器程式名稱和版本


      協商首部:

      Accept-Ranges: 對當前資源來講,伺服器所能夠接受的範圍型別

      Vary: 首部列表,伺服器會根據列表中的內容挑選出最適合的版本傳送給客戶端


      跟安全相關的響應首部:

             Set-Cookie: 伺服器端在某客戶端第一次請求時發給令牌

             Set-Cookie2: 

             WWW-Authentication: 質詢,即要求客戶提供帳號和密碼


實體首部:

      Location: 資源的新位置

      Allow: 允許對此資源使用的請求方法


      內容首部:

             Content-Encoding

             Content-Language

             Content-Length

             Content-Location

             Content-Range

             Content-Type


       快取首部:

              ETag: 實體標籤

              Expires: 過期期限

              Last-Modified: 上一次的修改時間


五、HTTPS

       目前有兩種方法來建立安全超文字協議連線:HTTPS URI方案和HTTP 1.1請求頭(由RFC2817引入)。由於瀏覽器對後者的幾乎沒有任何支援,因此HTTPS URI方案仍是建立安全超文字協議連線的主要手段。安全超文字連線協議使用https://代替http://

安全方法

       對於GET和HEAD方法而言,除了進行獲取資源資訊外,這些請求不應當再有其他意義。也就是說,這些方法應當被認為是“安全的”。客戶端可能會使用其他“非安全”方法,例如POST,PUT及DELETE,應該以特殊的方式(通常是按鈕而不是超連結)告知客戶可能的後果(例如一個按鈕控制的資金交易),或請求的操作可能是不安全的(例如某個檔案將被上傳或刪除)。

但是,不能想當然地認為伺服器在處理某個GET請求時不會產生任何副作用。事實上,很多動態資源會把這作為其特性。這裡重要的區別在於使用者並沒有請求這一副作用,因此不應由使用者為這些副作用承擔責任。

副作用

       假如在不考慮諸如錯誤或者過期等問題的情況下,若干次請求的副作用與單次請求相同或者根本沒有副作用,那麼這些請求方法就能夠被視作“冪等”的。 GET,HEAD,PUT和DELETE方法都有這樣的冪等屬性,同樣由於根據協議,OPTIONS,TRACE都不應有副作用,因此也理所當然也是冪等 的。

假 如某個由若干個請求做成的請求序列產生的結果在重複執行這個請求序列或者其中任何一個或多個請求後仍沒有發生變化,則這個請求序列便是“冪等”的。但是,可能出現若干個請求做成的請求序列是“非冪等”的,即使這個請求序列中所有執行的請求方法都是冪等的。例如,這個請求序列的結果依賴於某個會在下次執行這 個序列的過程中被修改的變數。


六、持續連線

       在 HTTP 0.9和1.0使用非持續連線,在非持續連線下,每個tcp只連線一個web物件,連線在每個請求-回應對後都會關閉,一個連線可被多個請求重 複利用的保持連線機制被引入。這種連線持續化顯著地減少了請求延遲,因為客戶不用在首次請求後再次進行TCP互動確認建立連線。現在在HTTP 1.1使用持續連線,不必為每個web物件建立一個新的連線,一個連線可以傳送多個物件。 HTTP1.1還進行了頻寬優化,例如1.1引入了分塊傳輸編碼來允許流化傳輸持續連線上傳送的內容,取代原先的buffer式傳輸。HTTP管道允許客戶在上一個回應被收到前傳送多重請求從而進一步減少了延遲時間。

另一項協議的改進是byte serving(位元組服務),允許伺服器根據客戶的請求僅僅傳輸資源的一部分。


七、HTTP協議例子:

下面是一個我通過瀏覽器自帶的開發工具HTTP客戶端與伺服器之間會話的例子,執行於www.google.com,埠80

客戶端請求報文:

1
2
3
4
5
6
7
8
GET / HTTP/1.1
Host: www.google.com.hk
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Cookie: PREF=ID=1737e66a16d71100:U=18298c26ad246c7f:FF=1:LD=zh-CN:NW=1:TM=1392034889:LM=1395146306:GM=1:S=oDsIzDBU1QId5BJy; NID=67=q2AFerfuDoSCSUYh8cLAHL3bJTcwBl0TF9COVot2bYGOUdauofGqlCr9eVtH68IOhIsggtl9bYk2k4O94fqhAW3pCSKTqA5aGqowV0u9ymWksMy8Fjd0KIsvEgXaroa7; OGPC=270001-1:
Connection: keep-alive

伺服器應答報文:

1
2
3
4
5
6
7
8
9
10
11
HTTP/1.1 200 OK
Alternate-Protocol: 443:quic
Cache-Control: private, max-age=0
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Wed, 19 Mar 2014 05:35:06 GMT
Expires: -1
Server: gws
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Firefox-Spdy: 3.1

     在HTTP1.0,單一TCP連線內僅執行一個“客戶端傳送請求—伺服器傳送應答”週期,之後釋放TCP連線。在HTTP1.1優化支援持續活躍連線:客戶端連續多次傳送請求、接收應答;批量多請求時,同一TCP連線在活躍(Keep-Live)間期內複用,避免重複TCP初始握手活動,減少網路負荷和響應週期。此外支援應答到達前繼續傳送請求(通常是兩個),稱為“流線化”(stream)。


參考文章:http://maoqiu.blog.51cto.com/8570467/1381723