【轉載】理解HTTP協議

在互聯網時代HTTP協議的重要性無需多言,對於技術崗位的同窗們來講理解掌握HTTP協議是必須的。本篇博客就從HTTP協議的演進、特性、重要知識點和工做中常見問題的總結等方面進行簡單的介紹。理解掌握了這些點工做中就OK了,固然在面試中也是少不了的,若是能結合實踐掌握這篇博客的80%應對通常的面試應該是夠了。若是要深刻學習HTTP協議的細節請看那本經典的《HTTP權威指南》。html

1、HTTP協議的演進面試

HTTP(HyperText Transfer Protocol)協議是基於TCP的應用層協議,它不關心數據傳輸的細節,主要是用來規定客戶端和服務端的數據傳輸格式,最初是用來向客戶端傳輸HTML頁面的內容。默認端口是80。瀏覽器

一、HTTP 0.9版本 1991年緩存

這個版本就是最初用來向客戶端傳輸HTML頁面的,因此只有一個GET命令,而後服務器返回客戶端一個HTML頁面,不能是其餘格式。利用這個版本徹底能夠構建一個簡單的靜態網站了。安全

二、HTTP 1.0版本 1996年服務器

1.0版本是改變比較大的,奠基瞭如今HTTP協議的基礎。這個版本的協議不只能夠傳輸HTML的文本頁面,還能夠傳輸其餘二進制文件,例如圖片、視頻。並且還增長了如今經常使用的POST和HEAD命令。請求消息和響應消息也不是單一的了,規定了一些元數據字段。例如字符集、編碼、狀態響應碼等。網絡

三、HTTP 1.1版本 1997年 app

其實是在1.0版本以後半年時間又發佈了一個版本,這個版本在1.0版本的基礎上更加完善了。這個版本增長了持久鏈接,就是說以前版本的協議一次請求就是一次TCP鏈接,請求完成後這個鏈接就關閉掉了。衆所周知TCP協議是可靠的,創建鏈接須要3次握手,斷開鏈接須要4次揮手,而且TCP有流量控制和擁塞控制,有慢開始機制,剛創建鏈接時傳輸比較慢,這是比較耗費資源的。一個豐富的頁面會有許多圖片、表單和超連接。這樣的話就會有屢次的HTTP請求,因此在這個版本上默認不關閉TCP鏈接也不用聲明Connection: keep-alive字段。若是確實要關閉能夠指定Connection: close字段。還引入了管道機制,就是說在一個TCP鏈接裏能夠同時發送多個HTTP請求,而沒必要等待上一個請求響應成功再發送。還增長了PUT、PATCH、HEAD、 OPTIONS、DELETE等命令,豐富了客戶端和服務端交互動做。還增長了Host字段。框架

四、HTTP 2版本 2015年 分佈式

這個版本也是隨着互聯網的發展,有了新的需求制定了新的功能還有對上一個版本的完善。1.1版本有了管道機制,可是正在服務端仍是要對請求進行排隊處理。這個版本能夠多工的處理。還有了頭信息壓縮和服務器的主動推送。

五、HTTPS

HTTPS是HTTP協議的安全版本,HTTP協議的數據傳輸是明文的,是不安全的,HTTPS使用了SSL/TLS協議進行了加密處理。

關於HTTP協議歷史演進的詳細介紹請參考:http://www.ruanyifeng.com/blo...

下面介紹沒有特殊說明默認HTTP/1.1版本

2、HTTP協議的特色

一、HTTP協議是無狀態的

就是說每次HTTP請求都是獨立的,任何兩個請求之間沒有什麼必然的聯繫。可是在實際應用當中並非徹底這樣的,引入了Cookie和Session機制來關聯請求。

二、屢次HTTP請求

在客戶端請求網頁時多數狀況下並非一次請求就能成功的,服務端首先是響應HTML頁面,而後瀏覽器收到響應以後發現HTML頁面還引用了其餘的資源,例如,CSS,JS文件,圖片等等,還會自動發送HTTP請求這些須要的資源。如今的HTTP版本支持管道機制,能夠同時請求和響應多個請求,大大提升了效率。

三、基於TCP協議

HTTP協議目的是規定客戶端和服務端數據傳輸的格式和數據交互行爲,並不負責數據傳輸的細節。底層是基於TCP實現的。如今使用的版本當中是默認持久鏈接的,也就是屢次HTTP請求使用一個TCP鏈接。

3、HTTP報文

一、請求報文

舉例:

GET /wxisme HTTP/1.1     
Host: www.cnblogs.com    
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; zh-CN; rv:1.8.1) Gecko/20061010 Firefox/2.0     
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5     
Accept-Language: en-us,zh-cn;q=0.7,zh;q=0.3     
Accept-Encoding: gzip,deflate     
Accept-Charset: gb2312,utf-8;q=0.7,*;q=0.7     
Keep-Alive: 300     
Proxy-Connection: keep-alive     
Cookie: ASP.NET_SessionId=ey5drq45lsomio55hoydzc45Cache-Control: max-age=0

簡單來講請求報文就是由請求行、請求頭、內容實體組成的,注意,每一行的末尾都有回車和換行,在內容實體和請求頭之間另有一個空行。其中請求行指定的是請求方法、請求URL、協議版本;請求頭是鍵值對的形式存在的,就是字段名:值;內容實體就是要傳輸的數據。稍後會對方法、請求頭字段作詳細的說明。

二、響應報文

舉例:

HTTP/1.1 200 OK
Date: Tue, 12 Jul 2016 21:36:12 
GMTContent-Length: 563
Content-Type: text/html
<html>    
    <body>    
        Hello http!    
    </body>
</html>

簡單來講響應報文由狀態行、響應首部字段(響應頭)、響應實體組成,其中第一行是狀態行,依次包含HTTP版本,狀態碼和狀態短語組成;在一個回車換行以後是響應頭,也是鍵值對的形式,字段名:值;而後會有一個空行也包含回車換行,以後是響應實體,就是要傳輸的數據。在上面的例子當中就是一個很是簡單的HTML頁面。對於響應狀態碼,首部字段鍵值對稍後會有更加詳細的說明。

4、HTTP請求方法

請求方法是客戶端用來告知服務器其動做意圖的方法。就像下達命令同樣。在HTTP1.1版本中支持GET、POST等近10種方法。須要注意的是方法名區分大小寫,須要用大寫字母。下面詳細說明。

一、GET:獲取資源

GET方法用來請求訪問已被URI識別的資源。也就是指定了服務器處理請求以後響應的內容。

二、POST:傳輸實體主體

POST方法用來傳輸實體主體。POST與GET的區別之一就是目的不一樣,兩者之間的區別會在文章的最後詳細說明。雖然GET方法也能夠傳輸,可是通常不用,由於GET的目的是獲取,POST的目的是傳輸。

三、PUT:傳輸文件

PUT方法用來傳輸文件。相似FTP協議,文件內容包含在請求報文的實體中,而後請求保存到URL指定的服務器位置。

四、HEAD:得到報文首部

HEAD方法相似GET方法,可是不一樣的是HEAD方法不要求返回數據。用於確認URI的有效性及資源更新時間等。

五、DELETE:刪除文件

DELETE方法用來刪除文件,是與PUT相反的方法。DELETE是要求返回URL指定的資源。

六、OPTIONS:詢問支持的方法

由於並非全部的服務器都支持規定的方法,爲了安全有些服務器可能會禁止掉一些方法例如DELETE、PUT等。那麼OPTIONS就是用來詢問服務器支持的方法。

七、TRACE:追蹤路徑

TRACE方法是讓Web服務器將以前的請求通訊環回給客戶端的方法。這個方法並不經常使用。

八、CONNECT:要求用隧道協議鏈接代理

CONNECT方法要求在與代理服務器通訊時創建隧道,實現用隧道協議進行TCP通訊。主要使用SSL/TLS協議對通訊內容加密後傳輸。

彙總:

5、HTTP的響應狀態碼

狀態碼是用來告知客戶端服務器端處理請求的結果。憑藉狀態碼用戶能夠知道服務器是請求處理成功、失敗或者是被轉發;這樣出現了錯誤也好定位。狀態碼是由3位數字加緣由短語組成。3位數字中的第一位是用來指定狀態的類別。共有5種。

HTTP狀態碼一共有60多種,可是不用所有都記住,由於大部分在工做當中是不常用的。常用的大概就是16種,下面來詳細介紹。(其實最最經常使用的也就8種,下面有背景色的就是)

一、200:OK

這個沒有什麼好說的,是表明請求被正常的處理成功了。

二、 204:No Content

請求處理成功,可是沒有數據實體返回,也不容許有實體返回。好比說HEAD請求,可能就會返回204 No Content,由於HEAD就是隻獲取頭信息。這裏簡單提一下205 Reset Content,和204 No Content的區別是不但沒有數據實體返回,並且還須要重置表單,方便用戶再次輸入。

三、206:Partial Content

這是客戶端使用Content-Range指定了須要的實體數據的範圍,而後服務端處理請求成功以後返回用戶須要的這一部分數據而不是所有,執行的請求就是GET。返回碼就是206:Partial Content。

四、301 : Moved Permanently

表明永久性定向。該狀態碼錶示請求的資源已經被分配了新的URL,之後應該使用資源如今指定的URL。也就是說若是已經把資源對應的URL保存爲書籤了,這是應該按照Location首部字段提示的URL從新保存。

五、302:Found

表明臨時重定向。該狀態碼錶示請求的資源已經被分配了新的URL,可是和301的區別是302表明的不是永久性的移動,只是臨時的。就是說這個URL還可能會發生改變。若是保存成書籤了也不會更新。

六、303:See Other

和302的區別是303明確規定客戶端應當使用GET方法。

七、304:Not Modified

該狀態碼錶示客戶端發送附帶條件請求時,服務器端容許請求訪問資源,可是沒有知足條件。304狀態碼返回時不包含任何數據實體。304雖然被劃分在3XX中可是和重定向沒有關係。

八、307:Temporary Redirect

臨時重定向,與302 Found相同,可是302會把POST改爲GET,而307就不會。

九、400:Bad Request

400表示請求報文中存在語法錯誤。須要修改後再次發送。

十、401:Unauthorized

該狀態碼錶示發送的請求須要有經過HTTP認證的認證信息。

十一、403:Forbidden

代表請求訪問的資源被拒絕了。沒有得到服務器的訪問權限,IP被禁止等。

十二、404:Not Found

代表請求的資源在服務器上找不到。固然也能夠在服務器拒絕請求且不想說明理由時使用。

1三、408:Request Timeout

表示客戶端請求超時,就是在客戶端和服務器創建鏈接後服務器在必定時間內沒有收到客戶端的請求。

1四、500:Internal Server Error

代表服務器端在執行請求時發生了錯誤,頗有多是服務端程序的Bug或者臨時故障。

1五、503:Service Unavailable

代表服務器暫時處於超負載或正在進行停機維護,如今沒法處理請求。若是事先得知解除以上情況須要的時間,最好寫入Retry-After字段再返回給客戶端。

1六、504:Getaway Timeout

網關超時,是代理服務器等待應用服務器響應時的超時,和408 Request Timeout的卻別就是504是服務器的緣由而不是客戶端的緣由

更加詳細的狀態碼請參考:http://tool.oschina.net/commo...

6、HTTP的首部字段

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

通用首部字段(General Header Fields)

表明請求報文和響應報文都會使用的字段

請求首部字段(Request Header Fields)

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

響應首部字段(Response Header Fields)

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

實體首部字段(Entity Header Fields)

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

在HTTP/1.1種規定了47種首部字段(圖表參考《圖解HTTP》,感謝做者。)

通用首部字段

請求首部字段

響應首部字段

實體首部字段

其餘首部字段

Cookie、Set-Cookie、Content-Disposition、Connection、Keep-Alive、Proxy-Authenticate、Proxy-Authorization、Trailer、TE、Transfer-Encoding、Upgrade etc...

這麼多的首部字段,估計若是不是很瞭解會被嚇着,可是根本不用所有記住,其實字段的名字就說明了做用,看一眼就大概知道是幹啥的了,只不過有些相似的字段要區分一下就行了。只要深入理解了HTTP的設計思路就沒有大問題了,熟悉常見的就能夠了。用到的時候想了解細節再去查。

關於首部字段的細節請參考《圖解HTTP》或者《HTTP權威指南》的首部字段部分。夠再寫一篇長博客的了~

以上就把HTTP協議的重點內容——報文格式、方法、狀態碼、首部字段介紹完了,能夠說對HTTP協議有了一些瞭解。下面就工做中的常見問題(或者說面試中的)作一個總結。^_^

7、關於HTTP的常見問題及解答

一、GET和POST的區別

A. 從字面意思和HTTP的規範來看,GET用於獲取資源信息而POST是用來更新資源信息。

B. GET提交請求的數據實體會放在URL的後面,用?來分割,參數用&鏈接,舉個栗子:/index.html?name=wang&login=1

C. GET提交的數據長度是有限制的,由於URL長度有限制,具體的長度限制視瀏覽器而定。而POST沒有。

D. GET提交的數據不安全,由於參數都會暴露在URL上。

二、408 Request Timeout和504 Gateway Timeout的區別

408是說請求超時,就是創建鏈接以後再約定的時間內客戶端沒有發送請求到客戶端到服務端。本質上緣由在於客戶端或者網絡擁塞。504是網關超時,是說代理服務器把客戶端請求轉發到應用服務器後再約定的時間內沒有收到應用服務器的響應。本質上緣由在於服務端的響應過慢,也有多是網絡問題。

三、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的優缺點針對不一樣的問題來設計解決方案。

相關文章
相關標籤/搜索