我是一名程序員,我的主要編程語言是 Java,我更是一名 Web 開發(fā)人員,所以我必須要了解 HTTP,所以本篇文章就來帶你從 HTTP 入門到進(jìn)階,看完讓你有一種恍然大悟、醍醐灌頂?shù)母杏X。
最初在有網(wǎng)絡(luò)之前,我們的電腦都是單機(jī)的,單機(jī)系統(tǒng)是孤立的,我還記得 05 年前那會(huì)兒家里有個(gè)電腦,想打電腦游戲還得兩個(gè)人在一個(gè)電腦上玩兒,及其不方便。我就想為什么家里人不讓上網(wǎng),我的同學(xué) xxx 家里有網(wǎng),每次一提這個(gè)就落一通批評(píng):xxx上xxx什xxxx么xxxx網(wǎng)xxxx看xxxx你xxxx考xxxx的xxxx那xxxx點(diǎn)xxxx分。雖然我家里沒有上網(wǎng),但是此時(shí)互聯(lián)網(wǎng)已經(jīng)在高速發(fā)展了,HTTP 就是高速發(fā)展的一個(gè)產(chǎn)物。
首先你聽的最多的應(yīng)該就是 HTTP 是一種 超文本傳輸協(xié)議(Hypertext Transfer Protocol)
,這你一定能說出來,但是這樣還不夠,假如你是大廠面試官,這不可能是他想要的最終結(jié)果,我們?cè)诿嬖嚨臅r(shí)候往往把自己知道的盡可能多的說出來,才有和面試官談價(jià)錢的資本。那么什么是超文本傳輸協(xié)議?
超文本傳輸協(xié)議可以進(jìn)行文字分割:超文本(Hypertext)、傳輸(Transfer)、協(xié)議(Protocol),它們之間的關(guān)系如下
按照范圍的大小 協(xié)議 > 傳輸 > 超文本。下面就分別對(duì)這三個(gè)名次做一個(gè)解釋。
在互聯(lián)網(wǎng)早期的時(shí)候,我們輸入的信息只能保存在本地,無法和其他電腦進(jìn)行交互。我們保存的信息通常都以文本
即簡(jiǎn)單字符的形式存在,文本是一種能夠被計(jì)算機(jī)解析的有意義的二進(jìn)制數(shù)據(jù)包。而隨著互聯(lián)網(wǎng)的高速發(fā)展,兩臺(tái)電腦之間能夠進(jìn)行數(shù)據(jù)的傳輸后,人們不滿足只能在兩臺(tái)電腦之間傳輸文字,還想要傳輸圖片、音頻、視頻,甚至點(diǎn)擊文字或圖片能夠進(jìn)行超鏈接
的跳轉(zhuǎn),那么文本的語義就被擴(kuò)大了,這種語義擴(kuò)大后的文本就被稱為超文本(Hypertext)
。
那么我們上面說到,兩臺(tái)計(jì)算機(jī)之間會(huì)形成互聯(lián)關(guān)系進(jìn)行通信,我們存儲(chǔ)的超文本會(huì)被解析成為二進(jìn)制數(shù)據(jù)包,由傳輸載體(例如同軸電纜,電話線,光纜)負(fù)責(zé)把二進(jìn)制數(shù)據(jù)包由計(jì)算機(jī)終端傳輸?shù)搅硪粋€(gè)終端的過程(對(duì)終端的詳細(xì)解釋可以參考 你說你懂互聯(lián)網(wǎng),那這些你知道么?這篇文章)稱為傳輸(transfer)
。
通常我們把傳輸數(shù)據(jù)包的一方稱為請(qǐng)求方
,把接到二進(jìn)制數(shù)據(jù)包的一方稱為應(yīng)答方
。請(qǐng)求方和應(yīng)答方可以進(jìn)行互換,請(qǐng)求方也可以作為應(yīng)答方接受數(shù)據(jù),應(yīng)答方也可以作為請(qǐng)求方請(qǐng)求數(shù)據(jù),它們之間的關(guān)系如下
如圖所示,A 和 B 是兩個(gè)不同的端系統(tǒng),它們之間可以作為信息交換的載體存在,剛開始的時(shí)候是 A 作為請(qǐng)求方請(qǐng)求與 B 交換信息,B 作為響應(yīng)的一方提供信息;隨著時(shí)間的推移,B 也可以作為請(qǐng)求方請(qǐng)求 A 交換信息,那么 A 也可以作為響應(yīng)方響應(yīng) B 請(qǐng)求的信息。
協(xié)議這個(gè)名詞不僅局限于互聯(lián)網(wǎng)范疇,也體現(xiàn)在日常生活中,比如情侶雙方約定好在哪個(gè)地點(diǎn)吃飯,這個(gè)約定也是一種協(xié)議
,比如你應(yīng)聘成功了,企業(yè)會(huì)和你簽訂勞動(dòng)合同,這種雙方的雇傭關(guān)系也是一種 協(xié)議
。注意自己一個(gè)人對(duì)自己的約定不能成為協(xié)議,協(xié)議的前提條件必須是多人約定。
那么網(wǎng)絡(luò)協(xié)議是什么呢?
網(wǎng)絡(luò)協(xié)議就是網(wǎng)絡(luò)中(包括互聯(lián)網(wǎng))傳遞、管理信息的一些規(guī)范。如同人與人之間相互交流是需要遵循一定的規(guī)矩一樣,計(jì)算機(jī)之間的相互通信需要共同遵守一定的規(guī)則,這些規(guī)則就稱為網(wǎng)絡(luò)協(xié)議。
沒有網(wǎng)絡(luò)協(xié)議的互聯(lián)網(wǎng)是混亂的,就和人類社會(huì)一樣,人不能想怎么樣就怎么樣,你的行為約束是受到法律的約束的;那么互聯(lián)網(wǎng)中的端系統(tǒng)也不能自己想發(fā)什么發(fā)什么,也是需要受到通信協(xié)議約束的。
那么我們就可以總結(jié)一下,什么是 HTTP?可以用下面這個(gè)經(jīng)典的總結(jié)回答一下:HTTP 是一個(gè)在計(jì)算機(jī)世界里專門在兩點(diǎn)之間傳輸文字、圖片、音頻、視頻等超文本數(shù)據(jù)的約定和規(guī)范
隨著網(wǎng)絡(luò)世界演進(jìn),HTTP 協(xié)議已經(jīng)幾乎成為不可替代的一種協(xié)議,在了解了 HTTP 的基本組成后,下面再來帶你進(jìn)一步認(rèn)識(shí)一下 HTTP 協(xié)議。
網(wǎng)絡(luò)是一個(gè)復(fù)雜的系統(tǒng),不僅包括大量的應(yīng)用程序、端系統(tǒng)、通信鏈路、分組交換機(jī)等,還有各種各樣的協(xié)議組成,那么現(xiàn)在我們就來聊一下網(wǎng)絡(luò)中的協(xié)議層次。
為了給網(wǎng)絡(luò)協(xié)議的設(shè)計(jì)提供一個(gè)結(jié)構(gòu),網(wǎng)絡(luò)設(shè)計(jì)者以分層(layer)
的方式組織協(xié)議,每個(gè)協(xié)議屬于層次模型之一。每一層都是向它的上一層提供服務(wù)(service)
,即所謂的服務(wù)模型(service model)
。每個(gè)分層中所有的協(xié)議稱為 協(xié)議棧(protocol stack)
。因特網(wǎng)的協(xié)議棧由五個(gè)部分組成:物理層、鏈路層、網(wǎng)絡(luò)層、運(yùn)輸層和應(yīng)用層。我們采用自上而下的方法研究其原理,也就是應(yīng)用層 -> 物理層的方式。
應(yīng)用層是網(wǎng)絡(luò)應(yīng)用程序和網(wǎng)絡(luò)協(xié)議存放的分層,因特網(wǎng)的應(yīng)用層包括許多協(xié)議,例如我們學(xué) web 離不開的 HTTP
,電子郵件傳送協(xié)議 SMTP
、端系統(tǒng)文件上傳協(xié)議 FTP
、還有為我們進(jìn)行域名解析的 DNS
協(xié)議。應(yīng)用層協(xié)議分布在多個(gè)端系統(tǒng)上,一個(gè)端系統(tǒng)應(yīng)用程序與另外一個(gè)端系統(tǒng)應(yīng)用程序交換信息分組,我們把位于應(yīng)用層的信息分組稱為 報(bào)文(message)
。
因特網(wǎng)的運(yùn)輸層在應(yīng)用程序斷點(diǎn)之間傳送應(yīng)用程序報(bào)文,在這一層主要有兩種傳輸協(xié)議 TCP
和 UDP
,利用這兩者中的任何一個(gè)都能夠傳輸報(bào)文,不過這兩種協(xié)議有巨大的不同。
TCP 向它的應(yīng)用程序提供了面向連接的服務(wù),它能夠控制并確認(rèn)報(bào)文是否到達(dá),并提供了擁塞機(jī)制來控制網(wǎng)絡(luò)傳輸,因此當(dāng)網(wǎng)絡(luò)擁塞時(shí),會(huì)抑制其傳輸速率。
UDP 協(xié)議向它的應(yīng)用程序提供了無連接服務(wù)。它不具備可靠性的特征,沒有流量控制,也沒有擁塞控制。我們把運(yùn)輸層的分組稱為 報(bào)文段(segment)
因特網(wǎng)的網(wǎng)絡(luò)層負(fù)責(zé)將稱為 數(shù)據(jù)報(bào)(datagram)
的網(wǎng)絡(luò)分層從一臺(tái)主機(jī)移動(dòng)到另一臺(tái)主機(jī)。網(wǎng)絡(luò)層一個(gè)非常重要的協(xié)議是 IP
協(xié)議,所有具有網(wǎng)絡(luò)層的因特網(wǎng)組件都必須運(yùn)行 IP 協(xié)議,IP 協(xié)議是一種網(wǎng)際協(xié)議,除了 IP 協(xié)議外,網(wǎng)絡(luò)層還包括一些其他網(wǎng)際協(xié)議和路由選擇協(xié)議,一般把網(wǎng)絡(luò)層就稱為 IP 層,由此可知 IP 協(xié)議的重要性。
現(xiàn)在我們有應(yīng)用程序通信的協(xié)議,有了給應(yīng)用程序提供運(yùn)輸?shù)膮f(xié)議,還有了用于約定發(fā)送位置的 IP 協(xié)議,那么如何才能真正的發(fā)送數(shù)據(jù)呢?為了將分組從一個(gè)節(jié)點(diǎn)(主機(jī)或路由器)運(yùn)輸?shù)搅硪粋€(gè)節(jié)點(diǎn),網(wǎng)絡(luò)層必須依靠鏈路層提供服務(wù)。鏈路層的例子包括以太網(wǎng)、WiFi 和電纜接入的 DOCSIS
協(xié)議,因?yàn)閿?shù)據(jù)從源目的地傳送通常需要經(jīng)過幾條鏈路,一個(gè)數(shù)據(jù)包可能被沿途不同的鏈路層協(xié)議處理,我們把鏈路層的分組稱為 幀(frame)
雖然鏈路層的作用是將幀從一個(gè)端系統(tǒng)運(yùn)輸?shù)搅硪粋€(gè)端系統(tǒng),而物理層的作用是將幀中的一個(gè)個(gè) 比特
從一個(gè)節(jié)點(diǎn)運(yùn)輸?shù)搅硪粋€(gè)節(jié)點(diǎn),物理層的協(xié)議仍然使用鏈路層協(xié)議,這些協(xié)議與實(shí)際的物理傳輸介質(zhì)有關(guān),例如,以太網(wǎng)有很多物理層協(xié)議:關(guān)于雙絞銅線、關(guān)于同軸電纜、關(guān)于光纖等等。
五層網(wǎng)絡(luò)協(xié)議的示意圖如下
我們上面討論的計(jì)算網(wǎng)絡(luò)協(xié)議模型不是唯一的 協(xié)議棧
,ISO(國際標(biāo)準(zhǔn)化組織)提出來計(jì)算機(jī)網(wǎng)絡(luò)應(yīng)該按照7層來組織,那么7層網(wǎng)絡(luò)協(xié)議棧與5層的區(qū)別在哪里?
從圖中可以一眼看出,OSI 要比上面的網(wǎng)絡(luò)模型多了 表示層
和 會(huì)話層
,其他層基本一致。表示層主要包括數(shù)據(jù)壓縮和數(shù)據(jù)加密以及數(shù)據(jù)描述,數(shù)據(jù)描述使得應(yīng)用程序不必?fù)?dān)心計(jì)算機(jī)內(nèi)部存儲(chǔ)格式的問題,而會(huì)話層提供了數(shù)據(jù)交換的定界和同步功能,包括建立檢查點(diǎn)和恢復(fù)方案。
就如同各大郵箱使用電子郵件傳送協(xié)議 SMTP
一樣,瀏覽器是使用 HTTP 協(xié)議的主要載體,說到瀏覽器,你能想起來幾種?是的,隨著網(wǎng)景大戰(zhàn)結(jié)束后,瀏覽器迅速發(fā)展,至今已經(jīng)出現(xiàn)過的瀏覽器主要有
瀏覽器正式的名字叫做 Web Broser
,顧名思義,就是檢索、查看互聯(lián)網(wǎng)上網(wǎng)頁資源的應(yīng)用程序,名字里的 Web,實(shí)際上指的就是 World Wide Web
,也就是萬維網(wǎng)。
我們?cè)诘刂窓谳斎險(xiǎn)RL(即網(wǎng)址),瀏覽器會(huì)向DNS(域名服務(wù)器,后面會(huì)說)提供網(wǎng)址,由它來完成 URL 到 IP 地址的映射。然后將請(qǐng)求你的請(qǐng)求提交給具體的服務(wù)器,在由服務(wù)器返回我們要的結(jié)果(以HTML編碼格式返回給瀏覽器),瀏覽器執(zhí)行HTML編碼,將結(jié)果顯示在瀏覽器的正文。這就是一個(gè)瀏覽器發(fā)起請(qǐng)求和接受響應(yīng)的過程。
Web 服務(wù)器的正式名稱叫做 Web Server
,Web 服務(wù)器一般指的是網(wǎng)站服務(wù)器,上面說到瀏覽器是 HTTP 請(qǐng)求的發(fā)起方,那么 Web 服務(wù)器就是 HTTP 請(qǐng)求的應(yīng)答方,Web 服務(wù)器可以向?yàn)g覽器等 Web 客戶端提供文檔,也可以放置網(wǎng)站文件,讓全世界瀏覽;可以放置數(shù)據(jù)文件,讓全世界下載。目前最主流的三個(gè)Web服務(wù)器是Apache、 Nginx 、IIS。
CDN的全稱是Content Delivery Network
,即內(nèi)容分發(fā)網(wǎng)絡(luò)
,它應(yīng)用了 HTTP 協(xié)議里的緩存和代理技術(shù),代替源站響應(yīng)客戶端的請(qǐng)求。CDN 是構(gòu)建在現(xiàn)有網(wǎng)絡(luò)基礎(chǔ)之上的網(wǎng)絡(luò),它依靠部署在各地的邊緣服務(wù)器,通過中心平臺(tái)的負(fù)載均衡、內(nèi)容分發(fā)、調(diào)度等功能模塊,使用戶就近
獲取所需內(nèi)容,降低網(wǎng)絡(luò)擁塞,提高用戶訪問響應(yīng)速度和命中率。CDN的關(guān)鍵技術(shù)主要有內(nèi)容存儲(chǔ)
和分發(fā)技術(shù)
。
打比方說你要去亞馬遜上買書,之前你只能通過購物網(wǎng)站購買后從美國發(fā)貨過海關(guān)等重重關(guān)卡送到你的家里,現(xiàn)在在中國建立一個(gè)亞馬遜分基地,你就不用通過美國進(jìn)行郵寄,從中國就能把書盡快給你送到。
WAF 是一種 Web 應(yīng)用程序防護(hù)系統(tǒng)(Web Application Firewall,簡(jiǎn)稱 WAF),它是一種通過執(zhí)行一系列針對(duì)HTTP / HTTPS的安全策略
來專門為Web應(yīng)用提供保護(hù)的一款產(chǎn)品,它是應(yīng)用層面的防火墻
,專門檢測(cè) HTTP 流量,是防護(hù) Web 應(yīng)用的安全技術(shù)。
WAF 通常位于 Web 服務(wù)器之前,可以阻止如 SQL 注入、跨站腳本等攻擊,目前應(yīng)用較多的一個(gè)開源項(xiàng)目是 ModSecurity,它能夠完全集成進(jìn) Apache 或 Nginx。
WebService 是一種 Web 應(yīng)用程序,WebService是一種跨編程語言和跨操作系統(tǒng)平臺(tái)的遠(yuǎn)程調(diào)用技術(shù)。
Web Service 是一種由 W3C 定義的應(yīng)用服務(wù)開發(fā)規(guī)范,使用 client-server 主從架構(gòu),通常使用 WSDL 定義服務(wù)接口,使用 HTTP 協(xié)議傳輸 XML 或 SOAP 消息,它是一個(gè)基于 Web(HTTP)的服務(wù)架構(gòu)技術(shù),既可以運(yùn)行在內(nèi)網(wǎng),也可以在適當(dāng)保護(hù)后運(yùn)行在外網(wǎng)。
HTML 稱為超文本標(biāo)記語言,是一種標(biāo)識(shí)性的語言。它包括一系列標(biāo)簽.通過這些標(biāo)簽可以將網(wǎng)絡(luò)上的文檔格式統(tǒng)一,使分散的 Internet 資源連接為一個(gè)邏輯整體。HTML 文本是由 HTML 命令組成的描述性文本,HTML 命令可以說明文字,圖形、動(dòng)畫、聲音、表格、鏈接等。
Web 頁面(Web page)也叫做文檔,是由一個(gè)個(gè)對(duì)象組成的。一個(gè)對(duì)象(Objecy)
只是一個(gè)文件,比如一個(gè) HTML 文件、一個(gè) JPEG 圖形、一個(gè) Java 小程序或一個(gè)視頻片段,它們?cè)诰W(wǎng)絡(luò)中可以通過 URL
地址尋址。多數(shù)的 Web 頁面含有一個(gè) HTML 基本文件
以及幾個(gè)引用對(duì)象。
舉個(gè)例子,如果一個(gè) Web 頁面包含 HTML 文件和5個(gè) JPEG 圖形,那么這個(gè) Web 頁面就有6個(gè)對(duì)象:一個(gè) HTML 文件和5個(gè) JPEG 圖形。HTML 基本文件通過 URL 地址引用頁面中的其他對(duì)象。
在互聯(lián)網(wǎng)中,任何協(xié)議都不會(huì)單獨(dú)的完成信息交換,HTTP 也一樣。雖然 HTTP 屬于應(yīng)用層的協(xié)議,但是它仍然需要其他層次協(xié)議的配合完成信息的交換,那么在完成一次 HTTP 請(qǐng)求和響應(yīng)的過程中,需要哪些協(xié)議的配合呢?一起來看一下
TCP/IP
協(xié)議你一定聽過,TCP/IP 我們一般稱之為協(xié)議簇
,什么意思呢?就是 TCP/IP 協(xié)議簇中不僅僅只有 TCP 協(xié)議和 IP 協(xié)議,它是一系列網(wǎng)絡(luò)通信協(xié)議的統(tǒng)稱。而其中最核心的兩個(gè)協(xié)議就是 TCP / IP 協(xié)議,其他的還有 UDP、ICMP、ARP 等等,共同構(gòu)成了一個(gè)復(fù)雜但有層次的協(xié)議棧。
TCP 協(xié)議的全稱是 Transmission Control Protocol
的縮寫,意思是傳輸控制協(xié)議
,HTTP 使用 TCP 作為通信協(xié)議,這是因?yàn)?TCP 是一種可靠的協(xié)議,而可靠
能保證數(shù)據(jù)不丟失。
IP 協(xié)議的全稱是 Internet Protocol
的縮寫,它主要解決的是通信雙方尋址的問題。IP 協(xié)議使用 IP 地址
來標(biāo)識(shí)互聯(lián)網(wǎng)上的每一臺(tái)計(jì)算機(jī),可以把 IP 地址想象成為你手機(jī)的電話號(hào)碼,你要與他人通話必須先要知道他人的手機(jī)號(hào)碼,計(jì)算機(jī)網(wǎng)絡(luò)中信息交換必須先要知道對(duì)方的 IP 地址。(關(guān)于 TCP 和 IP 更多的討論我們會(huì)在后面詳解)
你有沒有想過為什么你可以通過鍵入 www.google.com
就能夠獲取你想要的網(wǎng)站?我們上面說到,計(jì)算機(jī)網(wǎng)絡(luò)中的每個(gè)端系統(tǒng)都有一個(gè) IP 地址存在,而把 IP 地址轉(zhuǎn)換為便于人類記憶的協(xié)議就是 DNS 協(xié)議
。
DNS 的全稱是域名系統(tǒng)(Domain Name System,縮寫:DNS)
,它作為將域名和 IP 地址相互映射的一個(gè)分布式數(shù)據(jù)庫,能夠使人更方便地訪問互聯(lián)網(wǎng)。
我們上面提到,你可以通過輸入 www.google.com
地址來訪問谷歌的官網(wǎng),那么這個(gè)地址有什么規(guī)定嗎?我怎么輸都可以?AAA.BBB.CCC 是不是也行?當(dāng)然不是的,你輸入的地址格式必須要滿足 URI
的規(guī)范。
URI
的全稱是(Uniform Resource Identifier),中文名稱是統(tǒng)一資源標(biāo)識(shí)符,使用它就能夠唯一地標(biāo)記互聯(lián)網(wǎng)上資源。
URL
的全稱是(Uniform Resource Locator),中文名稱是統(tǒng)一資源定位符,也就是我們俗稱的網(wǎng)址
,它實(shí)際上是 URI 的一個(gè)子集。
URI 不僅包括 URL,還包括 URN(統(tǒng)一資源名稱),它們之間的關(guān)系如下
HTTP 一般是明文傳輸,很容易被攻擊者竊取重要信息,鑒于此,HTTPS 應(yīng)運(yùn)而生。HTTPS 的全稱為 (Hyper Text Transfer Protocol over SecureSocket Layer),全稱有點(diǎn)長(zhǎng),HTTPS 和 HTTP 有很大的不同在于 HTTPS 是以安全為目標(biāo)的 HTTP 通道,在 HTTP 的基礎(chǔ)上通過傳輸加密和身份認(rèn)證保證了傳輸過程的安全性。HTTPS 在 HTTP 的基礎(chǔ)上增加了 SSL
層,也就是說 HTTPS = HTTP + SSL。(這塊我們后面也會(huì)詳談 HTTPS)
你是不是很好奇,當(dāng)你在瀏覽器中輸入網(wǎng)址后,到底發(fā)生了什么事情?你想要的內(nèi)容是如何展現(xiàn)出來的?讓我們通過一個(gè)例子來探討一下,我們假設(shè)訪問的 URL 地址為 http://www.someSchool.edu/someDepartment/home.index
,當(dāng)我們輸入網(wǎng)址并點(diǎn)擊回車時(shí),瀏覽器內(nèi)部會(huì)進(jìn)行如下操作
www.someSchool.edu
所在的地址,然后HTTP 客戶端進(jìn)程在 80 端口發(fā)起一個(gè)到服務(wù)器 www.someSchool.edu
的 TCP 連接(80 端口是 HTTP 的默認(rèn)端口)。在客戶和服務(wù)器進(jìn)程中都會(huì)有一個(gè)套接字
與其相連。someDepartment/home.index
的資源,我們后面會(huì)詳細(xì)討論 HTTP 請(qǐng)求報(bào)文。存儲(chǔ)器(RAM 或磁盤)
中檢索出對(duì)象 www.someSchool.edu/someDepartment/home.index,然后把檢索出來的對(duì)象進(jìn)行封裝,封裝到 HTTP 響應(yīng)報(bào)文中,并通過套接字向客戶進(jìn)行發(fā)送。至此,鍵入網(wǎng)址再按下回車的全過程就結(jié)束了。上述過程描述的是一種簡(jiǎn)單的請(qǐng)求-響應(yīng)
全過程,真實(shí)的請(qǐng)求-響應(yīng)情況可能要比上面描述的過程復(fù)雜很多。
從上面整個(gè)過程中我們可以總結(jié)出 HTTP 進(jìn)行分組傳輸是具有以下特征
我們上面描述了一下 HTTP 的請(qǐng)求響應(yīng)過程,流程比較簡(jiǎn)單,但是凡事就怕認(rèn)真,你這一認(rèn)真,就能拓展出很多東西,比如 HTTP 報(bào)文是什么樣的,它的組成格式是什么? 下面就來探討一下
HTTP 協(xié)議主要由三大部分組成:
起始行(start line)
:描述請(qǐng)求或響應(yīng)的基本信息;頭部字段(header)
:使用 key-value 形式更詳細(xì)地說明報(bào)文;消息正文(entity)
:實(shí)際傳輸?shù)臄?shù)據(jù),它不一定是純文本,可以是圖片、視頻等二進(jìn)制數(shù)據(jù)。其中起始行和頭部字段并成為 請(qǐng)求頭
或者 響應(yīng)頭
,統(tǒng)稱為 Header
;消息正文也叫做實(shí)體,稱為 body
。HTTP 協(xié)議規(guī)定每次發(fā)送的報(bào)文必須要有 Header,但是可以沒有 body,也就是說頭信息是必須的,實(shí)體信息可以沒有。而且在 header 和 body 之間必須要有一個(gè)空行(CRLF),如果用一幅圖來表示一下的話,我覺得應(yīng)該是下面這樣
我們使用上面的那個(gè)例子來看一下 http 的請(qǐng)求報(bào)文
如圖,這是 http://www.someSchool.edu/someDepartment/home.index
請(qǐng)求的請(qǐng)求頭,通過觀察這個(gè) HTTP 報(bào)文我們就能夠?qū)W到很多東西,首先,我們看到報(bào)文是用普通 ASCII
文本書寫的,這樣保證人能夠可以看懂。然后,我們可以看到每一行和下一行之間都會(huì)有換行,而且最后一行(請(qǐng)求頭部后)再加上一個(gè)回車換行符。
每個(gè)報(bào)文的起始行都是由三個(gè)字段組成:方法、URL 字段和 HTTP 版本字段。
HTTP 請(qǐng)求方法一般分為 8 種,它們分別是
GET 獲取資源
,GET 方法用來請(qǐng)求訪問已被 URI 識(shí)別的資源。指定的資源經(jīng)服務(wù)器端解析后返回響應(yīng)內(nèi)容。也就是說,如果請(qǐng)求的資源是文本,那就保持原樣返回;
POST 傳輸實(shí)體
,雖然 GET 方法也可以傳輸主體信息,但是便于區(qū)分,我們一般不用 GET 傳輸實(shí)體信息,反而使用 POST 傳輸實(shí)體信息,
PUT 傳輸文件,PUT 方法用來傳輸文件。就像 FTP 協(xié)議的文件上傳一樣,要求在請(qǐng)求報(bào)文的主體中包含文件內(nèi)容,然后保存到請(qǐng)求 URI 指定的位置。
但是,鑒于 HTTP 的 PUT 方法自身不帶驗(yàn)證機(jī)制,任何人都可以上傳文件 , 存在安全性問題,因此一般的 W eb 網(wǎng)站不使用該方法。若配合 W eb 應(yīng)用程序的驗(yàn)證機(jī)制,或架構(gòu)設(shè)計(jì)采用REST(REpresentational State Transfer,表征狀態(tài)轉(zhuǎn)移)
標(biāo)準(zhǔn)的同類 Web 網(wǎng)站,就可能會(huì)開放使用 PUT 方法。
HEAD 獲得響應(yīng)首部,HEAD 方法和 GET 方法一樣,只是不返回報(bào)文主體部分。用于確認(rèn) URI 的有效性及資源更新的日期時(shí)間等。
DELETE 刪除文件,DELETE 方法用來刪除文件,是與 PUT 相反的方法。DELETE 方法按請(qǐng)求 URI 刪除指定的資源。
OPTIONS 詢問支持的方法,OPTIONS 方法用來查詢針對(duì)請(qǐng)求 URI 指定的資源支持的方法。
TRACE 追蹤路徑,TRACE 方法是讓 Web 服務(wù)器端將之前的請(qǐng)求通信環(huán)回給客戶端的方法。
CONNECT 要求用隧道協(xié)議連接代理,CONNECT 方法要求在與代理服務(wù)器通信時(shí)建立隧道,實(shí)現(xiàn)用隧道協(xié)議進(jìn)行 TCP 通信。主要使用 SSL(Secure Sockets Layer,安全套接層)
和 TLS(Transport Layer Security,傳輸層安全)
協(xié)議把通信內(nèi)容加 密后經(jīng)網(wǎng)絡(luò)隧道傳輸。
我們一般最常用的方法也就是 GET 方法和 POST 方法,其他方法暫時(shí)了解即可。下面是 HTTP1.0 和 HTTP1.1 支持的方法清單
HTTP 協(xié)議使用 URI 定位互聯(lián)網(wǎng)上的資源。正是因?yàn)?URI 的特定功能,在互聯(lián)網(wǎng)上任意位置的資源都能訪問到。URL 帶有請(qǐng)求對(duì)象的標(biāo)識(shí)符。在上面的例子中,瀏覽器正在請(qǐng)求對(duì)象 /somedir/page.html
的資源。
我們?cè)偻ㄟ^一個(gè)完整的域名解析一下 URL
比如 http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument
這個(gè) URL 比較繁瑣了吧,你把這個(gè) URL 搞懂了其他的 URL 也就不成問題了。
首先出場(chǎng)的是 http
http://
告訴瀏覽器使用何種協(xié)議。對(duì)于大部分 Web 資源,通常使用 HTTP 協(xié)議或其安全版本,HTTPS 協(xié)議。另外,瀏覽器也知道如何處理其他協(xié)議。例如, mailto:
協(xié)議指示瀏覽器打開郵件客戶端;ftp:
協(xié)議指示瀏覽器處理文件傳輸。
第二個(gè)出場(chǎng)的是 主機(jī)
www.example.com
既是一個(gè)域名,也代表管理該域名的機(jī)構(gòu)。它指示了需要向網(wǎng)絡(luò)上的哪一臺(tái)主機(jī)發(fā)起請(qǐng)求。當(dāng)然,也可以直接向主機(jī)的 IP address 地址發(fā)起請(qǐng)求。但直接使用 IP 地址的場(chǎng)景并不常見。
第三個(gè)出場(chǎng)的是 端口
我們前面說到,兩個(gè)主機(jī)之間要發(fā)起 TCP 連接需要兩個(gè)條件,主機(jī) + 端口。它表示用于訪問 Web 服務(wù)器上資源的入口。如果訪問的該 Web 服務(wù)器使用HTTP協(xié)議的標(biāo)準(zhǔn)端口(HTTP為80,HTTPS為443)授予對(duì)其資源的訪問權(quán)限,則通常省略此部分。否則端口就是 URI 必須的部分。
上面是請(qǐng)求 URL 所必須包含的部分,下面就是 URL 具體請(qǐng)求資源路徑
第四個(gè)出場(chǎng)的是 路徑
/path/to/myfile.html
是 Web 服務(wù)器上資源的路徑。以端口后面的第一個(gè) /
開始,到 ?
號(hào)之前結(jié)束,中間的 每一個(gè)/
都代表了層級(jí)(上下級(jí))關(guān)系。這個(gè) URL 的請(qǐng)求資源是一個(gè) html 頁面。
緊跟著路徑后面的是 查詢參數(shù)
?key1=value1&key2=value2
是提供給 Web 服務(wù)器的額外參數(shù)。如果是 GET 請(qǐng)求,一般帶有請(qǐng)求 URL 參數(shù),如果是 POST 請(qǐng)求,則不會(huì)在路徑后面直接加參數(shù)。這些參數(shù)是用 & 符號(hào)分隔的鍵/值對(duì)
列表。key1 = value1 是第一對(duì),key2 = value2 是第二對(duì)參數(shù)
緊跟著參數(shù)的是錨點(diǎn)
#SomewhereInTheDocument
是資源本身的某一部分的一個(gè)錨點(diǎn)。錨點(diǎn)代表資源內(nèi)的一種“書簽”,它給予瀏覽器顯示位于該“加書簽”點(diǎn)的內(nèi)容的指示。例如,在HTML文檔上,瀏覽器將滾動(dòng)到定義錨點(diǎn)的那個(gè)點(diǎn)上;在視頻或音頻文檔上,瀏覽器將轉(zhuǎn)到錨點(diǎn)代表的那個(gè)時(shí)間。值得注意的是 # 號(hào)后面的部分,也稱為片段標(biāo)識(shí)符,永遠(yuǎn)不會(huì)與請(qǐng)求一起發(fā)送到服務(wù)器。
表示報(bào)文使用的 HTTP 協(xié)議版本。
這部分內(nèi)容只是大致介紹一下,內(nèi)容較多,后面會(huì)再以一篇文章詳述
在表述完了起始行之后我們?cè)賮砜匆幌?code>請(qǐng)求頭部,現(xiàn)在我們向上找,找到http://www.someSchool.edu/someDepartment/home.index
,來看一下它的請(qǐng)求頭部
Host: www.someschool.edu
Connection: close
User-agent: Mozilla/5.0
Accept-language: fr
這個(gè)請(qǐng)求頭信息比較少,首先 Host 表示的是對(duì)象所在的主機(jī)。你也許認(rèn)為這個(gè) Host 是不需要的,因?yàn)?URL 不是已經(jīng)指明了請(qǐng)求對(duì)象的路徑了嗎?這個(gè)首部行提供的信息是 Web 代理高速緩存
所需要的。Connection: close
表示的是瀏覽器需要告訴服務(wù)器使用的是非持久連接
。它要求服務(wù)器在發(fā)送完響應(yīng)的對(duì)象后就關(guān)閉連接。User-agent
: 這是請(qǐng)求頭用來告訴 Web 服務(wù)器,瀏覽器使用的類型是 Mozilla/5.0
,即 Firefox 瀏覽器。Accept-language
告訴 Web 服務(wù)器,瀏覽器想要得到對(duì)象的法語版本,前提是服務(wù)器需要支持法語類型,否則將會(huì)發(fā)送服務(wù)器的默認(rèn)版本。下面我們針對(duì)主要的實(shí)體字段進(jìn)行介紹(具體的可以參考 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers MDN 官網(wǎng)學(xué)習(xí))
HTTP 的請(qǐng)求標(biāo)頭分為四種: 通用標(biāo)頭
、請(qǐng)求標(biāo)頭
、響應(yīng)標(biāo)頭
和 實(shí)體標(biāo)頭
,依次來進(jìn)行詳解。
通用標(biāo)頭主要有三個(gè),分別是 Date
、Cache-Control
和 Connection
Date
Date 是一個(gè)通用標(biāo)頭,它可以出現(xiàn)在請(qǐng)求標(biāo)頭和響應(yīng)標(biāo)頭中,它的基本表示如下
Date: Wed, 21 Oct 2015 07:28:00 GMT
表示的是格林威治標(biāo)準(zhǔn)時(shí)間,這個(gè)時(shí)間要比北京時(shí)間慢八個(gè)小時(shí)
Cache-Control
Cache-Control 是一個(gè)通用標(biāo)頭,他可以出現(xiàn)在請(qǐng)求標(biāo)頭和響應(yīng)標(biāo)頭中,Cache-Control 的種類比較多,雖然說這是一個(gè)通用標(biāo)頭,但是有一些特性是請(qǐng)求標(biāo)頭具有的,有一些是響應(yīng)標(biāo)頭才有的。主要大類有 可緩存性
、閾值性
、 重新驗(yàn)證并重新加載
和其他特性
可緩存性是唯一響應(yīng)標(biāo)頭才具有的特性,我們會(huì)在響應(yīng)標(biāo)頭中詳述。
閾值性,這個(gè)我翻譯可能不準(zhǔn)確,它的原英文是 Expiration,我是根據(jù)它的值來翻譯的,你看到這些值可能會(huì)覺得我翻譯的有點(diǎn)道理
max-age
: 資源被認(rèn)為仍然有效的最長(zhǎng)時(shí)間,與 Expires
不同,這個(gè)請(qǐng)求是相對(duì)于 request標(biāo)頭的時(shí)間,而 Expires 是相對(duì)于響應(yīng)標(biāo)頭。(請(qǐng)求標(biāo)頭)s-maxage
: 重寫了 max-age 和 Expires 請(qǐng)求頭,僅僅適用于共享緩存,被私有緩存所忽略(這塊不理解,看完響應(yīng)頭的 Cache-Control 再進(jìn)行理解)(請(qǐng)求標(biāo)頭)max-stale
:表示客戶端將接受的最大響應(yīng)時(shí)間,以秒為單位。(響應(yīng)標(biāo)頭)min-fresh
: 表示客戶端希望響應(yīng)在指定的最小時(shí)間內(nèi)有效。(響應(yīng)標(biāo)頭)Connection
Connection 決定當(dāng)前事務(wù)(一次三次握手和四次揮手)完成后,是否會(huì)關(guān)閉網(wǎng)絡(luò)連接。Connection 有兩種,一種是持久性連接
,即一次事務(wù)完成后不關(guān)閉網(wǎng)絡(luò)連接
Connection: keep-alive
另一種是非持久性連接
,即一次事務(wù)完成后關(guān)閉網(wǎng)絡(luò)連接
Connection: close
HTTP1.1 其他通用標(biāo)頭如下
實(shí)體標(biāo)頭是描述消息正文內(nèi)容的 HTTP 標(biāo)頭。實(shí)體標(biāo)頭用于 HTTP 請(qǐng)求和響應(yīng)中。頭部Content-Length
、 Content-Language
、 Content-Encoding
是實(shí)體頭。
Content-Language: de-DE
Content-Language: en-US
Content-Language: de-DE, en-CA
Content-Encoding 這又是一個(gè)比較麻煩的屬性,這個(gè)實(shí)體報(bào)頭用來壓縮媒體類型。Content-Encoding 指示對(duì)實(shí)體應(yīng)用了何種編碼。
常見的內(nèi)容編碼有這幾種: gzip、compress、deflate、identity ,這個(gè)屬性可以應(yīng)用在請(qǐng)求報(bào)文和響應(yīng)報(bào)文中
Accept-Encoding: gzip, deflate //請(qǐng)求頭
Content-Encoding: gzip //響應(yīng)頭
下面是一些實(shí)體標(biāo)頭字段
上面給出的例子請(qǐng)求報(bào)文的屬性比較少,下面給出一個(gè) MDN 官網(wǎng)的例子
GET /home.html HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/testpage.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT
If-None-Match: c561c68d0ba92bbeb8b0fff2a9199f722e3a621a
Cache-Control: max-age=0
Host
Host 請(qǐng)求頭指明了服務(wù)器的域名(對(duì)于虛擬主機(jī)來說),以及(可選的)服務(wù)器監(jiān)聽的TCP端口號(hào)。如果沒有給定端口號(hào),會(huì)自動(dòng)使用被請(qǐng)求服務(wù)的默認(rèn)端口(比如請(qǐng)求一個(gè) HTTP 的 URL 會(huì)自動(dòng)使用80作為端口)。
Host: developer.mozilla.org
上面的 Accpet
、 Accept-Language
、Accept-Encoding
都是屬于內(nèi)容協(xié)商的請(qǐng)求標(biāo)頭,我們會(huì)在下面說明
Referer
HTTP Referer 屬性是請(qǐng)求標(biāo)頭的一部分,當(dāng)瀏覽器向 web 服務(wù)器發(fā)送請(qǐng)求的時(shí)候,一般會(huì)帶上 Referer,告訴服務(wù)器該網(wǎng)頁是從哪個(gè)頁面鏈接過來的,服務(wù)器因此可以獲得一些信息用于處理。
Referer: https://developer.mozilla.org/testpage.html
Upgrade-Insecure-Requests
Upgrade-Insecure-Requests 是一個(gè)請(qǐng)求標(biāo)頭,用來向服務(wù)器端發(fā)送信號(hào),表示客戶端優(yōu)先選擇加密及帶有身份驗(yàn)證的響應(yīng)。
Upgrade-Insecure-Requests: 1
If-Modified-Since
HTTP 的 If-Modified-Since 使其成為條件請(qǐng)求
:
If-Modified-Since 通常會(huì)與 If-None-Match 搭配使用,If-Modified-Since 用于確認(rèn)代理或客戶端擁有的本地資源的有效性。獲取資源的更新日期時(shí)間,可通過確認(rèn)首部字段 Last-Modified
來確定。
大白話說就是如果在 Last-Modified
之后更新了服務(wù)器資源,那么服務(wù)器會(huì)響應(yīng)200,如果在 Last-Modified
之后沒有更新過資源,則返回 304。
If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT
If-None-Match
If-None-Match HTTP請(qǐng)求標(biāo)頭使請(qǐng)求成為條件請(qǐng)求。對(duì)于 GET 和 HEAD 方法,僅當(dāng)服務(wù)器沒有與給定資源匹配的 ETag
時(shí),服務(wù)器才會(huì)以200狀態(tài)發(fā)送回請(qǐng)求的資源。對(duì)于其他方法,僅當(dāng)最終現(xiàn)有資源的ETag
與列出的任何值都不匹配時(shí),才會(huì)處理請(qǐng)求。
If-None-Match: c561c68d0ba92bbeb8b0fff2a9199f722e3a621a
ETag 屬于響應(yīng)標(biāo)頭,后面進(jìn)行介紹。
內(nèi)容協(xié)商機(jī)制是指客戶端和服務(wù)器端就響應(yīng)的資源內(nèi)容進(jìn)行交涉,然后提供給客戶端最為適合的資源。內(nèi)容協(xié)商會(huì)以響應(yīng)資源的語言、字符集、編碼方式等作為判斷的標(biāo)準(zhǔn)。
內(nèi)容協(xié)商主要有以下3種類型:
服務(wù)器驅(qū)動(dòng)協(xié)商(Server-driven Negotiation)
這種協(xié)商方式是由服務(wù)器端進(jìn)行內(nèi)容協(xié)商。服務(wù)器端會(huì)根據(jù)請(qǐng)求首部字段進(jìn)行自動(dòng)處理
客戶端驅(qū)動(dòng)協(xié)商(Agent-driven Negotiation)
這種協(xié)商方式是由客戶端來進(jìn)行內(nèi)容協(xié)商。
透明協(xié)商(Transparent Negotiation)
是服務(wù)器驅(qū)動(dòng)和客戶端驅(qū)動(dòng)的結(jié)合體,是由服務(wù)器端和客戶端各自進(jìn)行內(nèi)容協(xié)商的一種方法。
內(nèi)容協(xié)商的分類有很多種,主要的幾種類型是 Accept、Accept-Charset、Accept-Encoding、Accept-Language、Content-Language。
Accept
接受請(qǐng)求 HTTP 標(biāo)頭會(huì)通告客戶端其能夠理解的 MIME 類型
那么什么是 MIME 類型呢?在回答這個(gè)問題前你應(yīng)該先了解一下什么是 MIME
“MIME: MIME (Multipurpose Internet Mail Extensions) 是描述消息內(nèi)容類型的因特網(wǎng)標(biāo)準(zhǔn)。MIME 消息能包含文本、圖像、音頻、視頻以及其他應(yīng)用程序?qū)S玫臄?shù)據(jù)。
也就是說,MIME 類型其實(shí)就是一系列消息內(nèi)容類型的集合。那么 MIME 類型都有哪些呢?
文本文件
:text/html、text/plain、text/css、application/xhtml+xml、application/xml
圖片文件
:image/jpeg、image/gif、image/png
視頻文件
:video/mpeg、video/quicktime
應(yīng)用程序二進(jìn)制文件
:application/octet-stream、application/zip
比如,如果瀏覽器不支持 PNG 圖片的顯示,那 Accept 就不指定image/png,而指定可處理的 image/gif 和 image/jpeg 等圖片類型。
一般 MIME 類型也會(huì)和 q
這個(gè)屬性一起使用,q 是什么?q 表示的是權(quán)重,來看一個(gè)例子
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
這是什么意思呢?若想要給顯示的媒體類型增加優(yōu)先級(jí),則使用 q= 來額外表示權(quán)重值,沒有顯示權(quán)重的時(shí)候默認(rèn)值是1.0 ,我給你列個(gè)表格你就明白了
也就是說,這是一個(gè)放置順序,權(quán)重高的在前,低的在后,application/xml;q=0.9
是不可分割的整體。
Accept-Charset
accept-charset 屬性規(guī)定服務(wù)器處理表單數(shù)據(jù)所接受的字符集。
accept-charset 屬性允許您指定一系列字符集,服務(wù)器必須支持這些字符集,從而得以正確解釋表單中的數(shù)據(jù)。
該屬性的值是用引號(hào)包含字符集名稱列表。如果可接受字符集與用戶所使用的字符即不相匹配的話,瀏覽器可以選擇忽略表單或是將該表單區(qū)別對(duì)待。
此屬性的默認(rèn)值是 unknown
,表示表單的字符集與包含表單的文檔的字符集相同。
常用的字符集有:UTF-8 - Unicode 字符編碼 ;ISO-8859-1 - 拉丁字母表的字符編碼
Accept-Language
首部字段 Accept-Language 用來告知服務(wù)器用戶代理能夠處理的自然語言集(指中文或英文等),以及自然語言集的相對(duì)優(yōu)先級(jí)??梢淮沃付ǘ喾N自然語言集。和 Accept 首部字段一樣,按權(quán)重值 q
來表示相對(duì)優(yōu)先級(jí)。
Accept-Language: en-US,en;q=0.5
請(qǐng)求標(biāo)頭我們大概就介紹這幾種,后面會(huì)有一篇文章詳細(xì)深挖所有的響應(yīng)頭的,下面是一個(gè)響應(yīng)頭的匯總,基于 HTTP 1.1
響應(yīng)標(biāo)頭是可以在 HTTP 響應(yīng)種使用的 HTTP 標(biāo)頭,這聽起來是像一句廢話,不過確實(shí)是這樣解釋。并不是所有出現(xiàn)在響應(yīng)中的標(biāo)頭都是響應(yīng)標(biāo)頭。還有一些特殊的我們上面說過,有通用標(biāo)頭和實(shí)體標(biāo)頭也會(huì)出現(xiàn)在響應(yīng)標(biāo)頭中,比如 Content-Length
就是一個(gè)實(shí)體標(biāo)頭,但是,在這種情況下,這些實(shí)體請(qǐng)求通常稱為響應(yīng)頭。下面以一個(gè)例子為例和你探討一下響應(yīng)頭
200 OK
Access-Control-Allow-Origin: *
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Mon, 18 Jul 2016 16:06:00 GMT
Etag: c561c68d0ba92bbeb8b0f612a9199f722e3a621a
Keep-Alive: timeout=5, max=997
Last-Modified: Mon, 18 Jul 2016 02:36:04 GMT
Server: Apache
Set-Cookie: mykey=myvalue; expires=Mon, 17-Jul-2017 16:06:00 GMT; Max-Age=31449600; Path=/; secure
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
x-frame-options: DENY
響應(yīng)狀態(tài)碼
首先出現(xiàn)的應(yīng)該就是 200 OK
,這是 HTTP 響應(yīng)標(biāo)頭的狀態(tài)碼,它表示著響應(yīng)成功完成。HTTP 響應(yīng)標(biāo)頭的狀態(tài)碼有很多,并做了如下規(guī)定
以 2xx
為開頭的都表示請(qǐng)求成功響應(yīng)。
以 3xx
為開頭的都表示需要進(jìn)行附加操作以完成請(qǐng)求
以 4xx
的響應(yīng)結(jié)果表明客戶端是發(fā)生錯(cuò)誤的原因所在。
以 5xx
為開頭的響應(yīng)標(biāo)頭都表示服務(wù)器本身發(fā)生錯(cuò)誤
Access-Control-Allow-Origin
一個(gè)返回的 HTTP 標(biāo)頭可能會(huì)具有 Access-Control-Allow-Origin ,Access-Control-Allow-Origin
指定一個(gè)來源,它告訴瀏覽器允許該來源進(jìn)行資源訪問。否則-對(duì)于沒有憑據(jù)的請(qǐng)求 *
通配符,告訴瀏覽器允許任何源訪問資源。例如,要允許源 https://mozilla.org
的代碼訪問資源,可以指定:
Access-Control-Allow-Origin: https://mozilla.org
Vary: Origin
如果服務(wù)器指定單個(gè)來源而不是 *
通配符的話 ,則服務(wù)器還應(yīng)在 Vary 響應(yīng)標(biāo)頭中包含 Origin
,以向客戶端指示 服務(wù)器響應(yīng)將根據(jù)原始請(qǐng)求標(biāo)頭的值而有所不同。
Keep-Alive
上面我們提到,HTTP 報(bào)文標(biāo)頭會(huì)分為四種,這其實(shí)是按著上下文
來分類的
還有一種分類是根據(jù)代理
進(jìn)行分類,根據(jù)代理會(huì)分為端到端頭
和 逐跳標(biāo)頭
而 Keep-Alive 表示的是 Connection 非持續(xù)連接的存活時(shí)間,如下
Connection: Keep-Alive
Keep-Alive: timeout=5, max=997
Keep-Alive 有兩個(gè)參數(shù),它們是以逗號(hào)分隔的參數(shù)列表,每個(gè)參數(shù)由一個(gè)標(biāo)識(shí)符和一個(gè)由等號(hào) = 分隔的值組成。
timeout
:指示空閑連接必須保持打開狀態(tài)的最短時(shí)間(以秒為單位)。
max
:指示在關(guān)閉連接之前可以在此連接上發(fā)送的最大請(qǐng)求數(shù)。
上述 HTTP 代碼的意思就是限制最大的超時(shí)時(shí)間是 5s 和 最大的連接請(qǐng)求是 997 個(gè)。
Server
服務(wù)器標(biāo)頭包含有關(guān)原始服務(wù)器用來處理請(qǐng)求的軟件的信息。
應(yīng)該避免使用過于冗長(zhǎng)和詳細(xì)的 Server 值,因?yàn)樗鼈兛赡軙?huì)泄露內(nèi)部實(shí)施細(xì)節(jié),這可能會(huì)使攻擊者容易地發(fā)現(xiàn)并利用已知的安全漏洞。例如下面這種寫法
Server: Apache/2.4.1 (Unix)
Set-Cookie
Cookie 又是另外一個(gè)領(lǐng)域的內(nèi)容了,我們后面文章會(huì)說道 Cookie,這里需要記住 Cookie、Set-Cookie 和 Content-Disposition 等在其他 RFC 中定義的首部字段,它們不是屬于 HTTP 1.1 的首部字段,但是使用率仍然很高。
Transfer-Encoding
首部字段 Transfer-Encoding 規(guī)定了傳輸報(bào)文主體時(shí)采用的編碼方式。
Transfer-Encoding: chunked
HTTP /1.1 的傳輸編碼方式僅對(duì)分塊傳輸編碼有效。
X-Frame-Options
HTTP 首部字段是可以自行擴(kuò)展的。所以在 Web 服務(wù)器和瀏覽器的應(yīng)用上,會(huì)出現(xiàn)各種非標(biāo)準(zhǔn)的首部字段。
首部字段 X-Frame-Options
屬于 HTTP 響應(yīng)首部,用于控制網(wǎng)站內(nèi)容在其他 Web 網(wǎng)站的 Frame 標(biāo)簽內(nèi)的顯示問題。其主要目的是為了防止點(diǎn)擊劫持(clickjacking)攻擊。
下面是一個(gè)響應(yīng)頭的匯總,基于 HTTP 1.1
在 HTTP 協(xié)議通信交互中使用到的首部字段,不限于 RFC2616 中定義的 47 種首部字段。還有 Cookie、Set-Cookie 和 Content-Disposition 等在其他 RFC 中定義的首部字段,它們的使用頻率也很高。這些非正式的首部字段統(tǒng)一歸納在 RFC4229 HTTP Header Field Registrations 中。
HTTP 首部字段將定義成緩存代理和非緩存代理的行為,分成 2 種類型。
一種是 End-to-end
首部 和 Hop-by-hop
首部
這些標(biāo)頭必須發(fā)送給消息的最終接收者 : 請(qǐng)求的服務(wù)器,或響應(yīng)的客戶端。中間代理必須重新傳輸未經(jīng)修改的標(biāo)頭,并且緩存必須存儲(chǔ)這些信息
分在此類別中的首部只對(duì)單次轉(zhuǎn)發(fā)有效,會(huì)因通過緩存或代理而不再轉(zhuǎn)發(fā)。
下面列舉了 HTTP/1.1 中的逐跳首部字段。除這 8 個(gè)首部字段之外,其他所有字段都屬于端到端首部。
Connection、Keep-Alive、Proxy-Authenticate、Proxy-Authorization、Trailer、TE、Transfer-Encoding、Upgrade
HTTP 最重要也是最突出的優(yōu)點(diǎn)是 簡(jiǎn)單、靈活、易于擴(kuò)展。
HTTP 的協(xié)議比較簡(jiǎn)單,它的主要組成就是 header + body
,頭部信息也是簡(jiǎn)單的文本格式,而且 HTTP 的請(qǐng)求報(bào)文根據(jù)英文也能猜出來個(gè)大概的意思,降低學(xué)習(xí)門檻,能夠讓更多的人研究和開發(fā) HTTP 應(yīng)用。
所以,在簡(jiǎn)單的基礎(chǔ)上,HTTP 協(xié)議又多了靈活
和 易擴(kuò)展
的優(yōu)點(diǎn)。
HTTP 協(xié)議里的請(qǐng)求方法、URI、狀態(tài)碼、原因短語、頭字段等每一個(gè)核心組成要素都沒有被制定死,允許開發(fā)者任意定制、擴(kuò)充或解釋,給予了瀏覽器和服務(wù)器最大程度的信任和自由。
因?yàn)檫^于簡(jiǎn)單,普及,因此應(yīng)用很廣泛。因?yàn)?HTTP 協(xié)議本身不屬于一種語言,它并不限定某種編程語言或者操作系統(tǒng),所以天然具有跨語言、跨平臺(tái)的優(yōu)越性。而且,因?yàn)楸旧淼暮?jiǎn)單特性很容易實(shí)現(xiàn),所以幾乎所有的編程語言都有 HTTP 調(diào)用庫和外圍的開發(fā)測(cè)試工具。
隨著移動(dòng)互聯(lián)網(wǎng)的發(fā)展, HTTP 的觸角已經(jīng)延伸到了世界的每一個(gè)角落,從簡(jiǎn)單的 Web 頁面到復(fù)雜的 JSON、XML 數(shù)據(jù),從臺(tái)式機(jī)上的瀏覽器到手機(jī)上的各種 APP、新聞、論壇、購物、手機(jī)游戲,你很難找到一個(gè)沒有使用 HTTP 的地方。
無狀態(tài)其實(shí)既是優(yōu)點(diǎn)又是缺點(diǎn)。因?yàn)榉?wù)器沒有記憶能力,所以就不需要額外的資源來記錄狀態(tài)信息,不僅實(shí)現(xiàn)上會(huì)簡(jiǎn)單一些,而且還能減輕服務(wù)器的負(fù)擔(dān),能夠把更多的 CPU 和內(nèi)存用來對(duì)外提供服務(wù)。
既然服務(wù)器沒有記憶能力,它就無法支持需要連續(xù)多個(gè)步驟的事務(wù)
操作。每次都得問一遍身份信息,不僅麻煩,而且還增加了不必要的數(shù)據(jù)傳輸量。由此出現(xiàn)了 Cookie
技術(shù)。
HTTP 協(xié)議里還有一把優(yōu)缺點(diǎn)一體的雙刃劍,就是明文傳輸。明文意思就是協(xié)議里的報(bào)文(準(zhǔn)確地說是 header 部分)不使用二進(jìn)制數(shù)據(jù),而是用簡(jiǎn)單可閱讀的文本形式。
對(duì)比 TCP、UDP 這樣的二進(jìn)制協(xié)議,它的優(yōu)點(diǎn)顯而易見,不需要借助任何外部工具,用瀏覽器、Wireshark 或者 tcpdump 抓包后,直接用肉眼就可以很容易地查看或者修改,為我們的開發(fā)調(diào)試工作帶來極大的便利。
當(dāng)然缺點(diǎn)也是顯而易見的,就是不安全
,可以被監(jiān)聽和被窺探。因?yàn)闊o法判斷通信雙方的身份,不能判斷報(bào)文是否被更改過。
HTTP 的性能不算差,但不完全適應(yīng)現(xiàn)在的互聯(lián)網(wǎng),還有很大的提升空間。
參考資料:
https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Technical_overview
《極客時(shí)間》- 透視 HTTP 協(xié)議
https://developer.mozilla.org/en-US/docs/Web/HTTP
https://baike.baidu.com/item/WEB服務(wù)器/8390210?fr=aladdin
https://baike.baidu.com/item/內(nèi)容分發(fā)網(wǎng)絡(luò)/4034265
https://baike.baidu.com/item/HTML/97049?fr=aladdin
https://www.jianshu.com/p/3dd8f1879acb
《計(jì)算機(jī)網(wǎng)絡(luò)-自頂向下方法》
《圖解 HTTP》
HTTP協(xié)議的內(nèi)容協(xié)商
https://www.w3school.com.cn/tags/att_form_accept_charset.asp
聯(lián)系客服