HTTP協議簡介

關於HTTP協議的基本介紹。

HTTP協議是基於TCP/IP協議之上的應用層協議,主要用於規定互使用聯網中客戶端和服務器之間的通訊格式,不關心具體傳輸細節,默認80端口。對於Web開發,無論是前端仍是後端開發,瞭解HTTP協議是必備的一些基本知識。html

發展歷程

HTTP/0.9

於1991年發佈,只有一個GET命令,返回HTML格式內容。前端

HTTP/1.0

於1996年5月發佈,增長POST、HEAD命令,傳輸內容能夠說任意格式,再也不僅限於HTML,而且報文規定了一些元數據字段,好比字符集、狀態碼、編碼、緩存等。算法

HTTP/1.1

於1997年1月發佈,增長PUT\PATCH\DELETE等命令,並新增了一些功能機制:json

  • 持久鏈接(keep-alive可保持長鏈接,減小重複請求)。
  • 管道機制(pipelining,一個TCP鏈接中客戶端可同時發送多個請求)。Content-Length字段(報文內容長度)。
  • Host字段(用於指定服務器域名,能夠將請求發往同一臺服務器的不一樣站點)。1.1版本基本完善了HTTP協議,而且一直使用至今仍然是目前最流行的版本。

SPDY

於2009年由谷歌研發,使用多種新特性提升HTTP/1.1版本效率不高的問題。做爲HTTP/2版本草案,在HTTP/2發佈後已中止使用。後端

HTTP/2

於2015年發佈,基於谷歌的SPDY協議之上進行了小部分修改。主要有如下特色:瀏覽器

  • 二進制協議(HTTP/1.1版本頭信息使用文本格式,數據體能夠是文本或二進制格式,而HTTP/2版本則所有使用二進制格式,方便未來擴展)。
  • 多工傳輸(複用TCP鏈接,雙向實時通訊,客戶端服務器可同時發送多個請求和響應,而且不須要按照請求順序迴應,避免隊頭阻塞問題)。
  • 頭信息壓縮(HTTP協議是無狀態的,所以不少請求都須要帶上Cookie、User Agent等重複字段,影響效率。HTTP/2使用gzip、compress等算法壓縮頭信息後,而且在客戶端和服務器都維護一張頭信息表,記錄這些字段,從而提升速度)。

SSL/TLS

因爲HTTP通訊是全明文傳輸的,不少敏感信息容易被竊取。網景公司(Netspace),發明了SSL協議,用於對HTTP傳輸的內容進行安全加密。後來互聯網標準化組織IETF將SSL推廣並從新命名爲TLS協議,因此SSL和TLS基本是一個東西。緩存

HTTPS

HTTPS = HTTP + SSL/TLS,可進行加密傳輸、身份認證,默認443端口,須要使用CA證書,免費證書較少,需交費。HTTPS有如下幾個特色:
(1) 全部信息都是加密傳播,黑客沒法竊聽。
(2) 具備校驗機制,一旦被篡改,通訊雙方會馬上發現。
(3) 配備身份證書,防止身份被冒充。安全

QUIC

由谷歌制定的基於UDP的一種傳輸層協議,QUIC協議集成了TCP可靠傳輸機制、TLS安全加密、HTTP /2 多路併發流量複用技術。服務器

協議特色

因爲目前HTTP/2尚未普遍使用,HTTP/1.1仍舊是目前使用最普遍的版本,因此後面主要介紹HTTP/1.1版本的基本知識。沒有特指的狀況下HTTP即爲HTTP/1.1版本。cookie

HTTP的主要特色有如下幾點:

  1. 基於TCP協議:HTTP協議目的是規定客戶端和服務端數據傳輸的格式和數據交互行爲,並不負責數據傳輸的細節。底層是基於TCP實現的。
  2. 無狀態鏈接:HTTP協議自己不對請求和響應之間的通訊狀態進行保存。
  3. 屢次請求:因爲管道機制可實現一次TCP鏈接同時多個HTTP請求。客戶端請求服務器時先響應HTML,再請求加載CSS,JS,圖片等資源。
  4. 持久鏈接:當TCP鏈接創建後,只要任意一端沒有明確提出斷開鏈接,則保持TCP鏈接狀態。減小TCP重複創建和斷開的開銷及服務器端的負載。
  5. 使用Cookie和Session機制管理狀態:爲了實現保存通訊狀態,引入了Cookie和Session技術。好比用戶登陸網站跳轉到其餘頁面可以保存用戶狀態,而不須要從新登陸。
  6. 全明文傳輸: 報文數據不加密(這一方面從某種意義上也方便了開發人員調試bug),敏感信息易泄露。可經過在代碼上使用SSL/TLS協議改造系統,加密請求響應報文,需調試可將報文解密後保存到日誌中進行問題排查。
  7. 內容編碼: 因爲某些報文的內容過大,所以在傳輸時,爲了減小傳輸的時間,會採起一些壓縮的措施。
  8. 範圍請求: 當客戶端請求的數據內容過大時,好比請求一張很大的圖片,會發現有時候圖片是一塊一塊加載的。這就是由於設置了http請求的長度,這樣就能夠分塊的加載資源文件。在請求報文中使用Range屬性,在響應報文中使用Content-Type屬性均可以指定必定字節範圍的http請求。
  9. 多部分對象集合: 報文傳輸的內容,不只僅是一些字符串,還有多是一些圖片,字符,音樂二進制等混雜的內容。這就須要使用多部分對象集合,multipart。默認的狀況下form使用的編碼格式是:applicatin/x-www-form-urlencoded,這種編碼格式會把全部的內容進行編碼,不適合上傳文件這種狀況。multipart/form-data 會以控件爲基準,編碼form中的內容。application/x-www-form-urlencoded 會把form中的內容編碼成鍵值對的形式。

HTTP報文

HTTP報文能夠分爲請求報文、響應報文。每一個報文又包含三個部分首行、頭部和主體。報文主體無關緊要。

GET www.baidu.com HTTP/1.1

請求報文的首行叫請求行,包括請求方法、URL和HTTP版本。

HTTP/1.1 200 OK

響應報文的首行叫狀態行,包括HTTP版本,狀態碼和簡短緣由,其中緣由無關緊要。

HTTP協議簡介01—報文結構

頭部的各類協議字段經過鍵值對來保存,主體保存具體內容。首行、頭部和主體以及頭部的各項字段用回車換行(\r\n)分割,另外頭部和主體之間多一個空行,也就是有兩個連續的回車換行。
HTTP協議簡介02—報文實例

請求方法

請求方法是客戶端用來告知服務端其操做意圖的一個命令。經常使用的主要有GET、POST方法。其餘方法不經常使用瞭解一下便可。下面是幾種方法的說明:

  1. GET: 用於獲取資源。
  2. POST: 用於傳輸實體主體。
  3. PUT:用於傳輸文件。PUT方法用來傳輸文件。相似FTP協議,文件內容包含在請求報文的實體中,而後請求保存到URL指定的服務器位置。
  4. HEAD:獲取報文首部。HEAD方法相似GET方法,可是不一樣的是HEAD方法不要求返回數據。用於確認URI的有效性及資源更新時間等。
  5. DELETE:用於刪除文件。DELETE方法用來刪除文件,是與PUT相反的方法。DELETE是要求返回URL指定的資源。
  6. OPTIONS: 用於詢問服務器支持的請求方法。OPTIONS 方法用來查詢針對請求 URI 指定的資源支持的方法。有些服務器爲了安全考慮會將PUT、DELETE方法禁用,這時能夠先用OPTIONS查詢支持的方法。
  7. TRACE:追蹤路徑。TRACE方法是讓Web服務器將以前的請求通訊環回給客戶端的方法。這個方法並不經常使用。
  8. CONNECT:要求用隧道協議鏈接代理。CONNECT方法要求在與代理服務器通訊時創建隧道,實現用隧道協議進行TCP通訊。主要使用SSL/TLS協議對通訊內容加密後傳輸。

    響應狀態碼

    狀態碼是服務器用來告知客戶端處理請求的結果。憑藉狀態碼用戶能夠知道服務器是請求處理成功、失敗或者是被轉發;這樣出現了錯誤也好定位。狀態碼是由3位數字加緣由短語組成。3位數字中的第一位是用來指定狀態的類別。共有5種類型:
    HTTP協議簡介03-狀態碼
    狀態碼一共有60多種,常用的大概就是16種,其中加粗爲最多見的狀況:

  • 200: OK 表示請求處理成功。
  • 204: No Content 表示請求處理成功,但沒有數據實體返回。
  • 206: Partial Content 表示客戶端指定請求範圍,服務器成功執行了這部分的GET請求。響應報文中包含由請求頭Content-Range指定範圍的實體內容。
  • 301: Moved Permanently 表明永久性定向。該狀態碼錶示請求的資源已經被分配了新的URL,之後應該使用資源如今指定的URL。也就是說若是已經把資源對應的URL保存爲書籤了,這是應該按照Location首部字段提示的URL從新保存。
  • 302: Found 表明臨時重定向。該狀態碼錶示請求的資源已經被分配了新的URL,可是和301的區別是302表明的不是永久性的移動,只是臨時的。就是說這個URL還可能會發生改變。若是保存成書籤了也不會更新。
  • 303: See Other 和302的區別是303明確規定客戶端應當使用GET方法。當 30一、30二、303 響應狀態碼返回時,幾乎全部的瀏覽器都會把
    POST 改爲 GET,並刪除請求報文內的主體,以後請求會自動再次
    發送。30一、302 標準是禁止將 POST 方法改變成 GET 方法的,但實際使
    用時你們都會這麼作。
  • 304: Not Modified 表示客戶端發送附帶條件請求時,服務器端容許請求訪問資源,可是沒有知足條件。304狀態碼返回時不包含任何數據實體。304雖然被劃分在3XX中可是和重定向沒有關係。
  • 307: Temporary Redirect 臨時重定向,與302 Found相同,可是302會把POST改爲GET,而307就不會。
  • 400: Bad Request 表示請求報文中存在語法錯誤。須要修改後再次發送。
  • 401: Unauthorized 表示發生的請求須要有經過HTTP認證的認證信息。
  • 403: Forbidden 表示請求訪問資源被拒絕了。沒有得到服務器的訪問權限,IP被禁止等。
  • 404: Not Found 表示請求的資源在服務器上找不到。固然也能夠在服務器拒絕請求且不想說明理由時使用。
  • 408: Request Timeout 表示客戶端請求超時。就是在客戶端和服務器創建鏈接後服務器在必定時間內沒有收到客戶端的請求。
  • 500: Internal Server Error 代表服務器端在執行請求時發生了錯誤,頗有多是服務端程序的Bug或者臨時故障。
  • 503: Service Unavaliable 代表服務器暫時處於超負載或正在進行停機維護,如今沒法處理請求。若是事先得知解除以上情況須要的時間,最好寫入Retry-After字段再返回給客戶端。
  • 504: Gateway Timeout 表示網關超時,是代理服務器等待應用服務器響應時的超時,和408 Request Timeout的卻別就是504是服務器的緣由而不是客戶端的緣由。

很多返回的狀態碼響應都是錯誤的,可是用戶可能察覺不到這點。
好比 Web 應用程序內部發生錯誤,狀態碼依然返回 200 OK,這種
狀況也常常遇到。這時可查看相近的幾回請求信息。

更多狀態碼的詳細介紹請參考: http://tool.oschina.net/commons?type=5

HTTP首部字段

HTTP首部字段是構成HTTP報文最重要的元素之一。在客戶端與服務端以前進行信息傳遞的時候請求和響應都會使用首部字段,會傳遞一些重要的元信息。首部字段是以鍵值對的形式存在的。包含報文的主體大小、語言、認證信息等。HTTP首部字段包含4種類型:

  • 通用首部字段(General Header Fields) 表明請求報文和響應報文都會使用的字段。

HTTP協議簡介04-通用首部字段

  • 請求首部字段(Request Header Fields) 是客戶端向服務端發送請求時使用的首部字段。包含請求的附加內容、客戶端信息、響應內容相關優先級等信息。

HTTP協議簡介05-請求首部字段

  • 響應首部字段(Response Header Fields) 是服務端向客戶端返回響應時使用的首部字段,包含響應的附加內容,可能也會要求客戶端附加額外的內容信息。

HTTP協議簡介06-響應首部字段

  • 實體首部字段(Entity Header Fields) 是針對請求報文和響應報文的實體部分使用的首部。包含資源內容更新時間等和實體有關的信息。

HTTP協議簡介07-實體首部字段

其餘首部字段Cookie、Set-Cookie、Content-Disposition、Connection、Keep-Alive、Proxy-Authenticate、Proxy-Authorization、Trailer、TE、Transfer-Encoding、Upgrade etc...也很經常使用,關於首部字段的細節請參考《圖解HTTP》或者《HTTP權威指南》的首部字段部分。

常見頭部字段說明

  • Accept: Accept請求報頭域用於指定客戶端接受哪些類型的信息。e.g. Accept:text/html,代表客戶端但願接受html文本。
  • Accept-Charset: Accept-Charset請求報頭域用於指定客戶端接受的字符集。
  • Accept-Encoding: 客戶端用於指定可接受的內容編碼。
  • Authorization: Authorization請求報頭域主要用於證實客戶端有權查看某個資源。
  • User-Agent: 請求報頭域容許客戶端將它的操做系統、瀏覽器和其它屬性告訴服務器。
  • Location: 重定向地址。
  • Server: 服務器用來處理請求的軟件信息。
  • Content-Encoding: 響應報文采用何種編碼格式傳輸正文。主要的編碼方式有gzip,compress,deflate,identity。
  • Content-Language: 實體報頭域描述了資源所用的天然語言。
  • Content-Length: 實體正文的長度,以字節方式存儲的十進制數字來表示。
  • Content-Type: 響應報文的實體正文的媒體類型

相關概念介紹

與HTTP協議關聯比較密切的一些概念簡介:

  • IP協議: 位於網絡層,用於計算機之間的通訊。主要實現兩個基本功能:尋址和分段。IP能夠根據數據包包頭中包括的目的地址將數據包傳送到目的地址,在此過程當中IP負責選擇傳送的道路,這種選擇道路稱爲路由功能。
  • TCP協議: 位於傳輸層,用於應用程序之間的通訊。採用「三次握手」和「四次揮手」機制創建可靠性鏈接。好比快遞送貨,IP協議至關於填寫快遞單號的規則以及如何根據快遞單信息找到客戶。TCP協議至關於送貨的快遞員,先打電話確認信息,再將快遞送過去,最後由客戶簽收。
  • DNS協議: 用於域名解析,將域名轉換爲IP地址。
  • URI/URL
    • URL(統一資源定位符):表示資源的地點,具體指向(門牌號)。
    • URI(統一資源標識符):用字符串標識某些互聯網資源(該門牌號的地方具體有什麼資源)。
    • URL是URI的子集。
  • 媒體類型: 互聯網上有數千種不一樣的數據類型,http給每種須要經過http傳輸的對象都打上了MIME類型(MIME type)的數據格式標籤。媒體類型自身實際上包含兩部分。第一部分(斜線前)是頂級媒體類型,這部分描述了通用的類型信息以及經常使用處理規則。常見的頂級類型有:application,image,text,video和multipart。第二部分是
    子類型,描述一個很是具體的數據格式。常見的媒體類型有:
    • text/html: HTML格式的文本文檔。
    • text/plain: 普通的ASCII文本文檔。
    • text/xml: XML格式。
    • image/png、image/jpeg、image/gif:圖片類型。
    • application/xml: XML數據格式
    • application/json: JSON數據格式
    • application/x-www-form-urlencoded: form表單數據被編碼爲key/value格式發送到服務器(表單默認的提交數據的格式)。
    • multipart/form-data: 表單中進行文件上傳時,須要使用該格式。
    更多的文件格式及對應的媒體類型信息請參考:http://tool.oschina.net/commons

一次完整的瀏覽器請求響應流程

當咱們在瀏覽器地址欄輸入www.baidu.com回車後。這一瞬間發生的請求過程是這樣的:

  1. 使用DNS協議對www.baidu.com域名進行解析,獲得對應的IP地址。
  2. 而後經過IP協議根據IP地址找到目標服務器。
  3. 經過TCP協議發起三次握手創建TCP鏈接。
  4. 經過TCP鏈接通訊,瀏覽器發起HTTP請求。
  5. 服務器處理請求,瀏覽器獲得響應報文包含HTML代碼。
  6. 瀏覽器解析HTML代碼,再發起請求去獲取HTML中須要的CSS、JS、圖片等資源。
  7. 瀏覽器對頁面進行渲染並呈現給用戶。

    常見問題

    GET和POST區別

  8. GET方法只用來獲取資源,不會對資源狀態進行修改;而POST方法用來傳輸實體對象,可能會對資源進行修改。
  9. GET請求參數會放在URL上,使用?符號進行分割,參數之間使用&符號鏈接,而且由於URL長度會根據不一樣瀏覽器有不一樣長度的限制;而POST請求參數會放到請求主體中,沒有長度限制。
  10. GET請求參數在URL可直接查看,所以主要用於不敏感數據的快速查詢;而POST數據放在實體中相對私密一些,主要可用於資源的增刪改等操做。
  11. GET請求會被瀏覽器主動緩存,而POST不會,除非手動設置。
  12. 對參數的數據類型,GET只接受ASCII字符,而POST沒有限制編碼。

    Cookie和Session區別

    Cookie和Session都是爲了保存客戶端和服務端之間的交互狀態,實現機制不一樣,各有優缺點。首先一個最大的區別就是Cookie是保存在客戶端而Session就保存在服務端的。Cookie是客戶端請求服務端時服務器會將一些信息以鍵值對的形式返回給客戶端,保存在瀏覽器中,交互的時候能夠加上這些Cookie值。用Cookie就能夠方便的作一些緩存。Cookie的缺點是大小和數量都有限制;Cookie是存在客戶端的可能被禁用、刪除、篡改,是不安全的;Cookie若是很大,每次要請求都要帶上,這樣就影響了傳輸效率。Session是基於Cookie來實現的,不一樣的是Session自己存在於服務端,可是每次傳輸的時候不會傳輸數據,只是把表明一個客戶端的惟一ID(一般是JSESSIONID)寫在客戶端的Cookie中,這樣每次傳輸這個ID就能夠了。Session的優點就是傳輸數據量小,比較安全。可是Session也有缺點,就是若是Session不作特殊的處理容易失效、過時、丟失或者Session過多致使服務器內存溢出,而且要實現一個穩定可用安全的分佈式Session框架也是有必定複雜度的。在實際使用中就要結合Cookie和Session的優缺點針對不一樣的問題來設計解決方案。

參考資料

相關文章
相關標籤/搜索