一、什麼是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)支持客戶/服務器模式。支持基本認證和安全認證。
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:回顯服務器收到的請求,主要用於測試或診斷。
CONNECT:HTTP/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: p_w_picpaths/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
客戶端請求報文:
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
服務器應答報文:
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)。
下一篇介紹httpd常用三種MPM...