HTTP——須要知道的協議

本文屬於原創文章,轉載請註明--來自桃源小盼聊技術html

筆者語

做爲一個程序員,當咱們訪問一個接口,服務器接收到並返回結果,那麼中間的流程是怎麼處理的呢?這個請求是如何到達服務器,服務器又是怎樣返回內容的?程序員

若是沒有HTTP協議,接口請求具體實現的細節, 都須要每一個客戶端和服務器各自約定和實現,而本身的規則,又不能適用於別人。這給開發帶來了極大的不便,HTTP就是爲此而設計的。HTTP協議用來約定雙方的行爲規範,讓相關開發者按照相同的規則來開發網站和工具。web

HTTP協議就像發快遞時填寫的發貨單,規定必須填寫收貨人,地址和手機號碼,只有這樣才能準確送給收貨人。HTTP則是規定了如何在兩臺電腦間發送和接收超文本。算法

起源歷史

1980年,蒂姆·伯納斯·李在CERN(歐洲核子研究組織)時,爲了方便各地研究人員共享信息,提出了一個設想,"藉助於超文本,鏈接成可互相瀏覽的WWW(萬維網)項目"。chrome

到了1989年,伯納斯·李看到了將超本文與互聯網結合的機會,那時已經有了在電腦上顯示信息的超文本系統,也有了域名系統和TCP/IP網絡傳輸協議。伯納斯·李又爲此設計製做世界上第一個網頁瀏覽器和網頁服務器,將這一切組合起來,就能實現瀏覽處於世界任何地方服務器上的超文本信息。在這個過程當中,因爲TCP/IP協議族中沒有適合傳輸超文本的協議,李博士又發起了HTTP(超文本傳輸協議)的提議。瀏覽器

因而在1989年,HTTP協議誕生了。現現在最普遍使用的協議版本是在1999年制定的HTTP 1.1。緩存

蒂姆·伯納斯·李在2017年4月5日,得到了2016年度圖靈獎,被譽爲萬維網之父。他發明了瀏覽器, HTTP,HTML,URI等一系列相關的萬維網技術。安全

TCP/IP協議族

現實世界中的各行各業都有本身的行業規則,違反規則,步履艱難,而尊重規則,便如魚得水。網絡世界也須要各類各樣的規則,TCP/IP協議族就是這些規則的總稱。而HTTP協議是其中的一種,負責傳輸超文本(HyperText)。性能優化

TCP/IP協議族一共分爲四層,包含不一樣的協議。應用層、傳輸層、網絡層和鏈路層。服務器

這張圖簡單描述了,打開一個網站背後都發生了什麼?

http-1

  1. 經過DNS協議,得到訪問域名對應的服務器IP地址。DNS協議屬於應用層。
  2. 緊接着用到了HTTP協議,將生成的HTTP報文發送給服務器。HTTP協議屬於應用層。
  3. 數據在網絡中的傳輸是十分重要的,爲了保證數據傳輸的穩定性和完整性,制定了TCP協議,它將數據分割成報文段,按序號傳輸。TCP協議屬於傳輸層。
  4. 客戶端發起的請求,怎麼在衆多機器中找到對應那一臺,須要IP協議來尋找一條路徑。IP協議屬於網絡層。
  5. 最後服務器收到了請求,把響應內容按照以前的步驟,返回給客戶端。

HTTP協議概述

客戶端發出請求報文,服務器收到請求,通過處理,把響應報文返回客戶端,鏈接斷開,一次請求結束。HTTP協議是無狀態協議。

在1990年W3C發佈了第一個HTTP/0.9版本,這個版本只支持GET請求。

1996年發佈了HTTP/1.0版本,這是第一個普遍使用的版本,支持了多媒體類型和各類HTTP首部字段。

但真正應用至今的是在1999年發佈的HTTP/1.1版本,它修復了一些結構的缺陷,並引入了性能優化的措施。本文如下的內容都以HTTP/1.1爲基礎展開。

咱們用chrome瀏覽器打開http://www.w3c.org這個網站。打開開發者工具的network項,看看第一個請求的詳細信息。

http-2

請求報文由請求地址、請求方法、協議版本、首部字段和內容實體。

GET /index.html HTTP/1.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6)
Host: w3c.org
複製代碼

響應報文由狀態碼及解釋短語、協議版本、首部字段和響應實體。

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 137582
Server: Apache 0.84

<html>
  <body>Hello World</body>
</html>
複製代碼

HTTP請求方法

HTTP/1.1 支持多種請求方法,最經常使用的仍是get和post方法。

HTTP通訊是創建在TCP鏈接的基礎上,早期版本每次通訊都須要從新鏈接、斷開TCP。因此在HTTP/1.1下,實現了在一次TCP鏈接中進行屢次HTTP通訊的能力,大大提升了服務器的響應速度。同時也支持並行發送請求,通常瀏覽器是支持同時6個鏈接。

GET

gee方法是安全的請求方法,獲取已經存在的資源或者是查詢一些數據,一般會把請求參數拼接在url中。

HEAD

head方法也是安全的,但它與get的不一樣在於,它不會返回響應實體內容,只返回響應首部。通常會用來確認請求url的有效性。

POST

post方法會把請求內容放在請求實體中,而不是拼接在url中。因此通常查詢信息用GET方法,提交表單數據使用post方法。

OPTIONS

查詢指定url資源支持的請求方法,例如支持get和head。

TRACE

通常請求發出後,會通過多層代理服務器,這個方法就是用來確認請求發出後發生的一系列操做。但會引發跨站追蹤攻擊,通常不用。

PUT與DELETE

put是用來往服務器上傳文件,而delete就是刪除服務器上的文件。可是這兩個方法沒有驗證機制,會產生不安全問題,通常服務器都不作支持。

狀態碼

狀態碼用來表示服務器返回的請求結果。由三位數字加解釋短語組成,例如 200 ok。 雖然狀態碼有不少,可是也可分門別類,並不須要掌握全部,也對返回的結果有個大體的瞭解。

狀態碼 響應類別 緣由短語
1xx 信息性狀態碼(Informational) 服務器正在處理請求
2xx 成功狀態碼(Success) 請求已正常處理完畢
3xx 重定向狀態碼(Redirection) 須要進行額外操做以完成請求
4xx 客戶端錯誤狀態碼(Client Error) 客戶端緣由致使服務器沒法處理請求
5xx 服務器錯誤狀態碼(Server Error) 服務器緣由致使處理請求出錯

當咱們知道了,首位數字是定義狀態碼的類型後,理解更多的狀態碼也就簡單起來。 下面,再詳細介紹一些常見的狀態碼。

200 OK

這個是最多見的,表示請求在服務器被正確處理了。

204 No Content

請求在服務器端被正確處理了,可是返回的響應報文中沒有實體內容。通常用在只是客戶端向服務器發送信息,而服務器不用向客戶端返回什麼信息的狀況。

301 Moved Permanently

永久性重定向,表明資源的連接已經更換了url,在響應報文中會包含新的連接地址。

304 Not Modified

當發出的請求中有附加條件(首部字段有if-*)時,服務器容許訪問,可是不知足條件的狀況。

400 Bad Request

請求報文內容存在語法錯誤,服務器處理不了。

401 Unauthorized

發送的請求中含有HTTP認證信息,認證未經過。 返回401的響應必須包含一個適用於被請求資源的WWW-Authenticate首部以質詢用戶信息

403 Forbidden

請求的資源拒絕被訪問,通常是無權限訪問。

404 Not Found

這個也很常見,請求的資源服務器找不到。

500 Internal Server Error

服務器在處理請求時,出錯了。通常是服務器發生了異常情況。

HTTP首部

首部字段是爲了給瀏覽器和服務器提供報文主體大小、所使用的語言、認證信息等內容。通俗點講,瀏覽器和服務器會根據這些字段作出不一樣的反應,每一個字段至關於一條配置信息。 首部字段相似於鍵值對,請求報文和響應報文都包含首部信息。

這是一段請求首部字段,例如Accept表示瀏覽器能夠接受的響應報文實體類型。

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6,ja;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Host:www.w3.org
If-Modified-Since:Thu, 04 May 2017 23:40:12 GMT
If-None-Match:"a384-54ebb4b41af00;89-3f26bd17a2f00-gzip"
複製代碼

首部字段分爲了五種類型,通用首部、請求首部、響應首部、實體首部和拓展首部。

類型 說明
通用首部 是請求和響應都會用到的字段
請求首部 是客戶端向服務器發送請求時,報文中包含的首部字段
響應首部 是服務器向瀏覽器返回響應報文時,包含的首部字段
實體首部 是請求報文和響應報文中針對實體內容的首部字段
拓展首部 是非標準首部字段,由開發者根據自身需求自由定義和實現

如下列表,提供一些首部的簡單說明,每一個字段的具體使用都不同,實際應用仍是查看詳細介紹。

通用首部

字段名 說明
Cache-Control 控制緩存行爲
Pragma HTTP/1.0遺留字段,也是用於控制緩存機制
Transfer-Encoding 傳輸報文主體的編碼方式
Trailer 報文主體以後的首部字段,用於分塊傳輸
Upgrade 檢測HTTP協議是否可用更高版本
Connection 控制再也不轉發給代理的字段、鏈接的管理
Date 建立報文的日期
Via 追蹤客戶端與服務器之間報文的傳輸路徑,一般指代理服務器
Warning 緩存相關警告

請求首部

字段名 說明
Accept 客戶端可接受的媒體類型及相關優先級,q值表示權重
Accept-Charset 客戶端可接受的字符集及優先順序
Accept-Encoding 客戶端支持的內容編碼及優先順序
Accept-Language 客戶端可處理的天然語言集,以及優先級
Authorization 客戶端的認證信息,通常是證書信息
Host 請求資源所在服務器的主機名和端口號
If-Match 比較實體標記
If-Modified-Since 比較資源更新時間
If-None-Match 比較實體標記(與If-Match做用相反)
If-Range 資源未更新時發送實體Byte的範圍請求
If-Unmodified-Since 比較資源更新時間(與If-Modified-Since做用相反)
Max-Forwards 最大傳輸逐跳數(TRACE或OPTIONS方法會用到)
Range 範圍請求的實體字節段
Referer 請求頁面的原始url
TE 傳輸編碼及優先級
User-Agent 請求客戶端的自身信息

響應首部

字段名 說明
Accept-Ranges 服務器是否接受字節範圍請求
Age 服務器響應建立通過的時間
ETag 資源配置信息
Location 服務器告知客戶端重定向url
Proxy-Authorization 代理服務器向客戶端發起的認證信息
Retry-After 服務器告知客戶端再次請求的時間
Server 服務器應用名、版本號等相關信息
Vary 代理服務器的緩存管理信息
WWW-Authorization 服務器對客戶端的認證信息

實體首部

字段名 說明
Allow 資源支持的請求方法
Content-Encoding 實體內容的編碼方式
Content-Language 實體內容的天然語言集
Content-Length 實體內容字節長度
Content-Location 實體內容替代url
Content-MD5 實體內容的報文摘要
Content-Range 實體內容的位置範圍
Content-Type 實體內容對應的媒體類型
Expires 實體內容失效日期
Last-Modified 實體內容最後修改日期

Cookie

HTTP協議是無狀態的,若是咱們今天登陸了一個網站,明天從新打開網站時,能自動登陸,怎麼辦? 那就得靠cookie來解決了。它能在客戶端保存用戶的基本信息,當咱們下次訪問該網站,瀏覽器會把cookie一塊兒發送給服務器,服務器就會根據這些信息來判斷你是否登錄過。

cookie是網景公司的前僱員盧·蒙特利在1993年3月的發明的。cookie數據也是鍵值對的形式,它和網站以及網頁是關聯在一塊兒的。若是保存cookie值指定了網站地址,訪問其餘網站時並不會發送這些cookie值。

訪問一個網站,打開chrome的開發者工具,application中能夠看見cookie的信息。

http-3

cookie相關的首部字段

  • Expires:是用來設置cookie的絕對過時時間,默認cookie的生存週期是跟隨頁面的,頁面關閉即失效。
  • Max-Age:是用來設置cookie的相對過時時間,若是同時設置了Expires值,以Max-Age爲準。
  • path: 是用來指定與cookie綁定的網頁地址,默認狀況下,和該網頁同一目錄下的網頁也能訪問該cookie。
  • domain: 指定與該cookie綁定的域名,該域名下的網頁均可以訪問該cookie。
  • secure: 標明傳輸cookie值的方式。默認狀況下,cookie是在不安全的HTTP連接傳輸,若是設定了該值,cookie將必須處於更安全的方式下才能夠傳輸,好比接下來介紹的HTTPS。

cookie的缺陷

  • 傳輸:cookie在每一次的HTTP請求中都被附加發送,增長了傳輸流量。
  • 安全:cookie是明文傳輸,有安全性問題,會被劫持和篡改。
  • 大小:cookie有大小限制是4kb,更復雜的數據存儲是沒法知足的。

HTTPS

HTTP協議傳輸的數據是明文未加密的,爲了安全性,網景公司設計了SSL協議(安全套接層),用SSL創建一個安全的通訊線路後,就能夠在這條線路上進行普通的HTTP通訊了,與SSL組合起來就是 HTTPS了,不過如今使用更多的是TLS(安全層傳輸協議)。

網站使用HTTPS須要申請一個證書,由第三方的可信賴機構提供的,這是爲了防止身份假裝。

HTTPS的握手過程

http-4

  1. 客戶端發送協議版本,隨機碼,支持的加密算法和壓縮方法
  2. 服務器確認使用的協議版本和加密算法,生成隨機碼,發送服務器證書
  3. 客戶端驗證服務器證書,生成48字節key,使用服務器公鑰加密key,發送加密信息,客戶端握手結束
  4. 服務器將兩個隨機碼+key組合生成本次通訊密鑰,用來加密信息,服務器握手結束

接下來的通訊都將在此加密通訊下進行,以上任何確認過程失敗,都將斷開加密通訊。

插曲OpenSSL

看過錘子發佈會的,都知道這個組織,但具體幹什麼的恐怕也沒幾我的清楚。它是HTTPS中SSL和TLS的具體實現庫。 OpenSSL是一個開放源代碼的軟件庫包,應用程序可使用這個包來進行安全通訊,其主要庫是以C語言所寫成,實現了基本的加密功能,實現了SSL與TLS協議。OpenSSL能夠運行在絕大多數類Unix操做系統上,OpenVMS與 Microsoft Windows。

將來的HTTP/2

隨着互聯網的發展,web頁面的數據量暴增,服務多年的HTTP/1.1已經顯露疲態,因爲協議是固定的,因此瀏覽器,服務器和開發者等都經過各自的手段,來增強服務的響應能力,減緩HTTP/1.1的不足之處。

谷歌開發了SPDY這個實驗性協議來提高http的性能,HTTP/2的草案就是基於SPDY3.0展開的。HTTP/2的主要目標是改進傳輸性能,實現低延遲和高吞吐量。升級HTTP2不會影響原有的網站應用。

二進制分幀

HTTP/2將全部傳輸的信息分割爲更小的消息和幀,並對它們採用二進制格式的編碼。以前版本的數據傳輸都是純文本的方式,二進制的解析更高效,更準確。這是整個HTTP/2性能提高的基礎。

多路複用的流

當前問題: HTTP/1.1協議中,一個tcp鏈接處理一個HTTP請求。例如同時有A和B兩個請求,先發送A請求,A請求響應結束,再發送B請求,若是A請求處理的時間很長,B也只能等待,這樣就形成了線頭堵塞。目前每一個瀏覽器能夠同時發起6-8個tcp鏈接,也依然不能很好地解決大量請求的處理。就算開啓了管道機制,一個tcp鏈接同時發送A和B請求,B仍是會等在A以後響應。

HTTP/2的方式: HTTP/2中的請求都在一個tcp鏈接中處理,每一個請求和響應都被分解爲獨立的幀,而後並行交錯發送,再在另外一端從新組裝。請求之間再也不互相干擾,從而消除了沒必要要的等待和延遲,巨大地提高了性能。

頭部壓縮

因爲HTTP是無狀態的,因此每一次請求和響應都會攜帶頭信息,而其中不少頭信息是相同的,毫無疑問增長了傳輸的數據量。

因此HTTP/2設計了專門用於壓縮頭信息的HPACK算法,在客戶端和服務器端使用「首部表」來跟蹤和存儲以前發送的鍵值對,並進行更新替換。

服務器推送

當咱們訪問一個網頁時,服務器先返回HTML文檔,瀏覽器再根據這個文檔,去請求其中包含的圖片,樣式表和腳本。

而HTTP/2中,服務器能夠對一個客戶端發送多個響應,而無需客戶端再多起屢次請求,客戶端能夠控制該功能的開啓。

參考

  1. http超文本傳輸協議——維基百科
  2. 蒂姆·伯納斯·李——萬維網之父
  3. 超文本——百度百科
  4. HTTP 協議入門——阮一峯
  5. 99%的人理解錯 HTTP 中 GET 與 POST 的區別
  6. 一次完整的HTTP請求與響應涉及了哪些知識?
  7. 《圖解HTTP》
  8. 《HTTP權威指南》
相關文章
相關標籤/搜索