http簡介看這篇就夠了
什麼是協議
協議,網路協議的簡稱,網路協議是通訊計算機雙方必須共同遵從的一組約定。如怎麼樣建立連線、怎麼樣互相識別等。只有遵守這個約定,計算機之間才能相互通訊交流。它的三要素是:語法、語義、時序。
為了使資料在網路上從源到達目的,網路通訊的參與方必須遵循相同的規則,這套規則稱為協議(protocol),它最終體現為在網路上傳輸的資料包的格式。
協議往往分成幾個層次進行定義,分層定義是為了使某一層協議的改變不影響其他層次的協議。
http協議
超文字傳輸協議(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
1.0 版本
簡介
1996年5月,HTTP/1.0 版本釋出,內容大大增加。
首先,任何格式的內容都可以傳送。這使得網際網路不僅可以傳輸文字,還能傳輸影象、視訊、二進位制檔案。這為網際網路的大發展奠定了基礎。
其次,除了GET命令,還引入了POST命令和HEAD命令,豐富了瀏覽器與伺服器的互動手段。
再次,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連線就建立了,直到客戶端或伺服器主動關閉連線。但是,這不是標準欄位,不同實現的行為可能不一致,因此不是根本的解決辦法。
1.1 版本
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協議設計得更好一些,這些額外的工作是可以避免的。
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響應資料解析
請求的資料裡面包含三個部分內容 : 響應行 、 響應頭 、響應體
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 : 通訊的日期,響應的時間
HTTP之狀態碼
狀態程式碼有三位數字組成,第一個數字定義了響應的類別,共分五種類別:
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 //伺服器當前不能處理客戶端的請求,一段時間後可能恢復正常
Get 和 Post請求區別
post
資料是以流的方式寫過去,不會在位址列上面顯示。 現在一般提交資料到伺服器使用的都是POST
以流的方式寫資料,所以資料沒有大小限制。
get
會在位址列後面拼接資料,所以有安全隱患。 一般從伺服器獲取資料,並且客戶端也不用提交上面資料的時候,可以使用GET
能夠帶的資料有限, 1kb大小
HTTP工作原理
HTTP協議定義Web客戶端如何從Web伺服器請求Web頁面,以及伺服器如何把Web頁面傳送給客戶端。HTTP協議採用了請求/響應模型。客戶端向伺服器傳送一個請求報文,請求報文包含請求的方法、URL、協議版本、請求頭部和請求資料。伺服器以一個狀態行作為響應,響應的內容包括協議的版本、成功或者錯誤程式碼、伺服器資訊、響應頭部和響應資料。
以下是 HTTP 請求/響應的步驟:
1、客戶端連線到Web伺服器
一個HTTP客戶端,通常是瀏覽器,與Web伺服器的HTTP埠(預設為80)建立一個TCP套接字連線。
2、傳送HTTP請求
通過TCP套接字,客戶端向Web伺服器傳送一個文字的請求報文,一個請求報文由請求行、請求頭部、空行和請求資料4部分組成。
3、伺服器接受請求並返回HTTP響應
Web伺服器解析請求,定位請求資源。伺服器將資源複本寫到TCP套接字,由客戶端讀取。一個響應由狀態行、響應頭部、空行和響應資料4部分組成。
4、釋放連線TCP連線
若connection 模式為close,則伺服器主動關閉TCP連線,客戶端被動關閉連線,釋放TCP連線;若connection 模式為keepalive,則該連線會保持一段時間,在該時間內可以繼續接收請求;
5、客戶端瀏覽器解析HTML內容
客戶端瀏覽器首先解析狀態行,查看錶明請求是否成功的狀態程式碼。然後解析每一個響應頭,響應頭告知以下為若干位元組的HTML文件和文件的字符集。客戶端瀏覽器讀取響應資料HTML,根據HTML的語法對其進行格式化,並在瀏覽器視窗中顯示。
例如:在瀏覽器位址列鍵入URL,按下回車之後會經歷以下流程:
1、瀏覽器向 DNS 伺服器請求解析該 URL 中的域名所對應的 IP 地址;
2、解析出 IP 地址後,根據該 IP 地址和預設埠 80,和伺服器建立TCP連線;
3、瀏覽器發出讀取檔案(URL 中域名後面部分對應的檔案)的HTTP 請求,該請求報文作為 TCP 三次握手的第三個報文的資料傳送給伺服器;
4、伺服器對瀏覽器請求作出響應,並把對應的 html 文字傳送給瀏覽器;
5、釋放 TCP連線;
6、瀏覽器將該 html 文字並顯示內容;