文章有不當之處,歡迎指正,若是喜歡微信閱讀,你也能夠關注個人微信公衆號:
好好學java
,獲取優質學習資源。javascript
協議,網絡協議的簡稱,網絡協議是通訊計算機雙方必須共同聽從的一組約定。如怎麼樣創建鏈接、怎麼樣互相識別等。只有遵照這個約定,計算機之間才能相互通訊交流。它的三要素是:語法、語義、時序。css
爲了使數據在網絡上從源到達目的,網絡通訊的參與方必須遵循相同的規則,這套規則稱爲協議(protocol),它最終體現爲在網絡上傳輸的數據包的格式。html
協議每每分紅幾個層次進行定義,分層定義是爲了使某一層協議的改變不影響其餘層次的協議。java
超文本傳輸協議(HTTP,HyperText Transfer Protocol)是互聯網上應用最爲普遍的一種網絡協議。全部的WWW文件都必須遵照這個標準。設計HTTP最初的目的是爲了提供一種發佈和接收HTML頁面的方法。1960年美國人Ted Nelson構思了一種經過計算機處理文本信息的方法,並稱之爲超文本(hypertext),這成爲了HTTP超文本傳輸協議標準架構的發展根基。Ted Nelson組織協調萬維網協會(World Wide Web Consortium)和互聯網工程工做小組(Internet Engineering Task Force )共同合做研究,最終發佈了一系列的RFC,其中著名的RFC 2616定義了HTTP 1.1算法
簡介瀏覽器
1996年5月,HTTP/1.0 版本發佈,內容大大增長。緩存
首先,任何格式的內容均可以發送。這使得互聯網不只能夠傳輸文字,還能傳輸圖像、視頻、二進制文件。這爲互聯網的大發展奠基了基礎。安全
其次,除了GET命令,還引入了POST命令和HEAD命令,豐富了瀏覽器與服務器的互動手段。bash
再次,HTTP請求和迴應的格式也變了。除了數據部分,每次通訊都必須包括頭信息(HTTP header),用來描述一些元數據。服務器
其餘的新增功能還包括狀態碼(status code)、多字符集支持、多部分發送(multi-part type)、權限(authorization)、緩存(cache)、內容編碼(content encoding)等。
請求格式
下面是一個1.0版的HTTP請求的例子。
GET / HTTP/1.0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
複製代碼
能夠看到,這個格式與0.9版有很大變化。
第一行是請求命令,必須在尾部添加協議版本(HTTP/1.0)。後面就是多行頭信息,描述客戶端的狀況。
迴應格式
服務器的迴應以下。
HTTP/1.0 200 OK
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84
複製代碼
迴應的格式是"頭信息 + 一個空行(\r\n) + 數據"。其中,第一行是"協議版本 + 狀態碼(status code) + 狀態描述"。
Content-Type 字段
關於字符的編碼,1.0版規定,頭信息必須是 ASCII 碼,後面的數據能夠是任何格式。所以,服務器迴應的時候,必須告訴客戶端,數據是什麼格式,這就是Content-Type字段的做用。
下面是一些常見的Content-Type字段的值。
text/plain
text/html
text/css
image/jpeg
image/png
image/svg+xml
audio/mp4
video/mp4
application/javascript
application/pdf
application/zip
application/atom+xml
複製代碼
這些數據類型總稱爲MIME type,每一個值包括一級類型和二級類型,之間用斜槓分隔。
除了預約義的類型,廠商也能夠自定義類型。
application/vnd.debian.binary-package
複製代碼
上面的類型代表,發送的是Debian系統的二進制數據包。
MIME type還能夠在尾部使用分號,添加參數。
Content-Type: text/html; charset=utf-8
複製代碼
上面的類型代表,發送的是網頁,並且編碼是UTF-8。
客戶端請求的時候,可使用Accept字段聲明本身能夠接受哪些數據格式。
Accept: */*
複製代碼
上面代碼中,客戶端聲明本身能夠接受任何格式的數據。
MIME type不只用在HTTP協議,還能夠用在其餘地方,好比HTML網頁。
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- 等同於 -->
<meta charset="utf-8" />
複製代碼
Content-Encoding 字段
因爲發送的數據能夠是任何格式,所以能夠把數據壓縮後再發送。Content-Encoding字段說明數據的壓縮方法。
Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate
複製代碼
客戶端在請求時,用Accept-Encoding字段說明本身能夠接受哪些壓縮方法。
Accept-Encoding: gzip, deflate
複製代碼
缺點
HTTP/1.0 版的主要缺點是,每一個TCP鏈接只能發送一個請求。發送數據完畢,鏈接就關閉,若是還要請求其餘資源,就必須再新建一個鏈接。
TCP鏈接的新建成本很高,由於須要客戶端和服務器三次握手,而且開始時發送速率較慢(slow start)。因此,HTTP 1.0版本的性能比較差。隨着網頁加載的外部資源愈來愈多,這個問題就愈發突出了。
爲了解決這個問題,有些瀏覽器在請求時,用了一個非標準的Connection字段。
Connection: keep-alive
複製代碼
這個字段要求服務器不要關閉TCP鏈接,以便其餘請求複用。服務器一樣迴應這個字段。
Connection: keep-alive
複製代碼
一個能夠複用的TCP鏈接就創建了,直到客戶端或服務器主動關閉鏈接。可是,這不是標準字段,不一樣實現的行爲可能不一致,所以不是根本的解決辦法。
1997年1月,HTTP/1.1 版本發佈,只比 1.0 版本晚了半年。它進一步完善了 HTTP 協議,一直用到了20年後的今天,直到如今仍是最流行的版本。
持久鏈接
1.1 版的最大變化,就是引入了持久鏈接(persistent connection),即TCP鏈接默認不關閉,能夠被多個請求複用,不用聲明Connection: keep-alive。
客戶端和服務器發現對方一段時間沒有活動,就能夠主動關閉鏈接。不過,規範的作法是,客戶端在最後一個請求時,發送Connection: close,明確要求服務器關閉TCP鏈接。
Connection: close
複製代碼
目前,對於同一個域名,大多數瀏覽器容許同時創建6個持久鏈接。
管道機制
1.1 版還引入了管道機制(pipelining),即在同一個TCP鏈接裏面,客戶端能夠同時發送多個請求。這樣就進一步改進了HTTP協議的效率。
舉例來講,客戶端須要請求兩個資源。之前的作法是,在同一個TCP鏈接裏面,先發送A請求,而後等待服務器作出迴應,收到後再發出B請求。管道機制則是容許瀏覽器同時發出A請求和B請求,可是服務器仍是按照順序,先回應A請求,完成後再回應B請求。
Content-Length 字段
一個TCP鏈接如今能夠傳送多個迴應,勢必就要有一種機制,區分數據包是屬於哪個迴應的。這就是Content-length字段的做用,聲明本次迴應的數據長度。
Content-Length: 3495
複製代碼
上面代碼告訴瀏覽器,本次迴應的長度是3495個字節,後面的字節就屬於下一個迴應了。
在1.0版中,Content-Length字段不是必需的,由於瀏覽器發現服務器關閉了TCP鏈接,就代表收到的數據包已經全了。
分塊傳輸編碼
使用Content-Length字段的前提條件是,服務器發送迴應以前,必須知道迴應的數據長度。
對於一些很耗時的動態操做來講,這意味着,服務器要等到全部操做完成,才能發送數據,顯然這樣的效率不高。更好的處理方法是,產生一塊數據,就發送一塊,採用"流模式"(stream)取代"緩存模式"(buffer)。
所以,1.1版規定能夠不使用Content-Length字段,而使用"分塊傳輸編碼"(chunked transfer encoding)。只要請求或迴應的頭信息有Transfer-Encoding字段,就代表迴應將由數量未定的數據塊組成。
Transfer-Encoding: chunked
複製代碼
每一個非空的數據塊以前,會有一個16進制的數值,表示這個塊的長度。最後是一個大小爲0的塊,就表示本次迴應的數據發送完了。下面是一個例子。
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
25
This is the data in the first chunk
1C
and this is the second one
3
con
8
sequence
0
複製代碼
其餘功能
1.1版還新增了許多動詞方法:PUT、PATCH、HEAD、 OPTIONS、DELETE
。
另外,客戶端請求的頭信息新增了Host字段,用來指定服務器的域名。
Host: www.example.com
複製代碼
有了Host字段,就能夠將請求發往同一臺服務器上的不一樣網站,爲虛擬主機的興起打下了基礎。
缺點
雖然1.1版容許複用TCP鏈接,可是同一個TCP鏈接裏面,全部的數據通訊是按次序進行的。服務器只有處理完一個迴應,纔會進行下一個迴應。要是前面的迴應特別慢,後面就會有許多請求排隊等着。這稱爲"隊頭堵塞"(Head-of-line blocking)。
爲了不這個問題,只有兩種方法:一是減小請求數,二是同時多開持久鏈接。這致使了不少的網頁優化技巧,好比合並腳本和樣式表、將圖片嵌入CSS代碼、域名分片(domain sharding)等等。若是HTTP協議設計得更好一些,這些額外的工做是能夠避免的。
請求的數據裏面包含三個部份內容 : 請求行 、 請求頭 、請求體
POST /examples/servlets/servlet/RequestParamExample HTTP/1.1 //請求路徑
複製代碼
**POST :**請求方式 ,以post去提交數據
/examples/servlets/servlet/RequestParamExample 請求的地址路徑 , 就是要訪問哪一個地方。
HTTP/1.1: 協議版本
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
Referer: http://localhost:8080/examples/servlets/servlet/RequestParamExample
Accept-Language: zh-CN
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: localhost:8080
Content-Length: 31
Connection: Keep-Alive
Cache-Control: no-cache
複製代碼
Accept: 客戶端向服務器端表示,我能支持什麼類型的數據。 Referer : 真正請求的地址路徑,全路徑 Accept-Language: 支持語言格式 User-Agent: 用戶代理 向服務器代表,當前來訪的客戶端信息。 Content-Type: 提交的數據類型。通過urlencoding編碼的form表單的數據 Accept-Encoding: gzip, deflate : 壓縮算法 。 Host : 主機地址 Content-Length: 數據長度 Connection : Keep-Alive 保持鏈接 Cache-Control : 對緩存的操做
瀏覽器真正發送給服務器的數據
發送的數據呈現的是key=value
,若是存在多個數據,那麼使用 &firstname=zhang&lastname=sansan
請求的數據裏面包含三個部份內容 : 響應行 、 響應頭 、響應體
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 673
Date: Fri, 17 Feb 2017 02:53:02 GMT
...這裏還有不少數據...
複製代碼
HTTP/1.1 200 OK
複製代碼
HTTP/1.1:協議版本
200:狀態碼
我們此次交互究竟是什麼樣結果的一個code.
200 : 成功,正常處理,獲得數據。 403 : for bidden 拒絕 404 : Not Found 500 : 服務器異常
OK:對應前面的狀態碼
Server: 服務器是哪種類型。 Tomcat
Content-Type : 服務器返回給客戶端你的內容類型
Content-Length : 返回的數據長度
Date : 通信的日期,響應的時間
複製代碼
狀態代碼有三位數字組成,第一個數字定義了響應的類別,共分五種類別:
1xx:指示信息--表示請求已接收,繼續處理 2xx:成功--表示請求已被成功接收、理解、接受 3xx:重定向--要完成請求必須進行更進一步的操做 4xx:客戶端錯誤--請求有語法錯誤或請求沒法實現 5xx:服務器端錯誤--服務器未能實現合法的請求
常見狀態碼
200 OK //客戶端請求成功 400 Bad Request //客戶端請求有語法錯誤,不能被服務器所理解 401 Unauthorized //請求未經受權,這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用 403 Forbidden //服務器收到請求,可是拒絕提供服務 404 Not Found //請求資源不存在,eg:輸入了錯誤的URL 500 Internal Server Error //服務器發生不可預期的錯誤 503 Server Unavailable //服務器當前不能處理客戶端的請求,一段時間後可能恢復正常
更多狀態碼 www.runoob.com/http/http-s…
數據是以流的方式寫過去,不會在地址欄上面顯示。 如今通常提交數據到服務器使用的都是POST
以流的方式寫數據,因此數據沒有大小限制。
會在地址欄後面拼接數據,因此有安全隱患。 通常從服務器獲取數據,而且客戶端也不用提交上面數據的時候,可使用GET
可以帶的數據有限, 1kb大小
HTTP協議定義Web客戶端如何從Web服務器請求Web頁面,以及服務器如何把Web頁面傳送給客戶端。HTTP協議採用了請求/響應模型。客戶端向服務器發送一個請求報文,請求報文包含請求的方法、URL、協議版本、請求頭部和請求數據。服務器以一個狀態行做爲響應,響應的內容包括協議的版本、成功或者錯誤代碼、服務器信息、響應頭部和響應數據。
如下是 HTTP 請求/響應的步驟:
一、客戶端鏈接到Web服務器
一個HTTP客戶端,一般是瀏覽器,與Web服務器的HTTP端口(默認爲80)創建一個TCP套接字鏈接。
二、發送HTTP請求
經過TCP套接字,客戶端向Web服務器發送一個文本的請求報文,一個請求報文由請求行、請求頭部、空行和請求數據4部分組成。
三、服務器接受請求並返回HTTP響應
Web服務器解析請求,定位請求資源。服務器將資源複本寫到TCP套接字,由客戶端讀取。一個響應由狀態行、響應頭部、空行和響應數據4部分組成。
四、釋放鏈接TCP鏈接
若connection 模式爲close,則服務器主動關閉TCP鏈接,客戶端被動關閉鏈接,釋放TCP鏈接;若connection 模式爲keepalive,則該鏈接會保持一段時間,在該時間內能夠繼續接收請求;
五、客戶端瀏覽器解析HTML內容
客戶端瀏覽器首先解析狀態行,查看代表請求是否成功的狀態代碼。而後解析每個響應頭,響應頭告知如下爲若干字節的HTML文檔和文檔的字符集。客戶端瀏覽器讀取響應數據HTML,根據HTML的語法對其進行格式化,並在瀏覽器窗口中顯示。
例如:在瀏覽器地址欄鍵入URL,按下回車以後會經歷如下流程:
一、瀏覽器向 DNS 服務器請求解析該 URL 中的域名所對應的 IP 地址;
二、解析出 IP 地址後,根據該 IP 地址和默認端口 80,和服務器創建TCP鏈接;
三、瀏覽器發出讀取文件(URL 中域名後面部分對應的文件)的HTTP 請求,該請求報文做爲 TCP 三次握手的第三個報文的數據發送給服務器;
四、服務器對瀏覽器請求做出響應,並把對應的 html 文本發送給瀏覽器;
五、釋放 TCP鏈接;
六、瀏覽器將該 html 文本並顯示內容;