溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

HTTP 協(xié)議初探之--歷史演變和設(shè)計思路

發(fā)布時間:2020-07-03 19:32:00 來源:網(wǎng)絡(luò) 閱讀:292 作者:獨孤環(huán)宇 欄目:建站服務(wù)器

HTTP 協(xié)議是互聯(lián)網(wǎng)的基礎(chǔ)協(xié)議,也是網(wǎng)頁開發(fā)的必備知識,最新版本 HTTP 2 更是讓它成為技術(shù)熱點。

本文介紹 HTTP 協(xié)議的歷史演變和設(shè)計思路。

HTTP 簡介

HTTP 是基于 TCP/IP 協(xié)議的應(yīng)用層協(xié)議。它不涉及數(shù)據(jù)包(packet)傳輸主要規(guī)定了客戶端和服務(wù)器之間的通信格式,默認(rèn)使用80端口。

HTTP是Hyper Text Transfer Protocol(超文本傳輸協(xié)議)的縮寫,超文本傳輸協(xié)議)是用于從WWW服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議。它可以使瀏覽器更加高效,使網(wǎng)絡(luò)傳輸減少。

HTTP不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內(nèi)容首先顯示(如文本先于圖形)等。 HTTP是一個應(yīng)用層協(xié)議,由請求和響應(yīng)構(gòu)成,是一個標(biāo)準(zhǔn)的客戶端服務(wù)器模型。HTTP是一個無狀態(tài)的協(xié)議。

—-在TCP/IP協(xié)議棧中的位置

HTTP協(xié)議通常承載于TCP協(xié)議之上,有時也承載于TLS或SSL協(xié)議層之上,這個時候,就成了我們常說的HTTPS。如下圖所示:

HTTP 協(xié)議初探之--歷史演變和設(shè)計思路

默認(rèn)HTTP的端口號為80,HTTPS的端口號為443。

—-HTTP的請求響應(yīng)模型

HTTP協(xié)議永遠(yuǎn)都是客戶端發(fā)起請求,服務(wù)器回送響應(yīng)。見下圖:

HTTP 協(xié)議初探之--歷史演變和設(shè)計思路

這樣就限制了使用HTTP協(xié)議,無法實現(xiàn)在客戶端沒有發(fā)起請求的時候,服務(wù)器將消息推送給客戶端。 HTTP協(xié)議是一個無狀態(tài)的協(xié)議,同一個客戶端的這次請求和上次請求是沒有對應(yīng)關(guān)系。

—-工作流程

一次HTTP操作稱為一個事務(wù),其工作過程可分為四步: 
1)首先客戶機與服務(wù)器需要建立連接。只要單擊某個超級鏈接,HTTP的工作開始。

2)建立連接后,客戶機發(fā)送一個請求給服務(wù)器,請求方式的格式為:統(tǒng)一資源標(biāo)識符(URL)、協(xié)議版本號,后邊是MIME信息包括請求修飾符、客戶機信息和可能的內(nèi)容。

3)服務(wù)器接到請求后,給予相應(yīng)的響應(yīng)信息,其格式為一個狀態(tài)行,包括信息的協(xié)議版本號、一個成功或錯誤的代碼,后邊是MIME信息包括服務(wù)器信息、實體信息和可能的內(nèi)容。

4)客戶端接收服務(wù)器所返回的信息通過瀏覽器顯示在用戶的顯示屏上,然后客戶機與服務(wù)器斷開連接。 如果在以上過程中的某一步出現(xiàn)錯誤,那么產(chǎn)生錯誤的信息將返回到客戶端,有顯示屏輸出。對于用戶來說,這些過程是由HTTP自己完成的,用戶只要用鼠標(biāo)點擊,等待信息顯示就可以了。

—-HTTP協(xié)議的主要特點可概括如下:

1.支持客戶/服務(wù)器模式。

2.簡單快速:客戶向服務(wù)器請求服務(wù)時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規(guī)定了客戶與服務(wù)器聯(lián)系的類型不同。由于HTTP協(xié)議簡單,使得HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快。

3.靈活:HTTP允許傳輸任意類型的數(shù)據(jù)對象。正在傳輸?shù)念愋陀蒀ontent-Type加以標(biāo)記。

4.無連接:無連接的含義是限制每次連接只處理一個請求。服務(wù)器處理完客戶的請求,并收到客戶的應(yīng)答后,即斷開連接。采用這種方式可以節(jié)省傳輸時間。

5.無狀態(tài):HTTP協(xié)議是無狀態(tài)協(xié)議。無狀態(tài)是指協(xié)議對于事務(wù)處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導(dǎo)致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務(wù)器不需要先前信息時它的應(yīng)答就較快。


以下是“HTTP 協(xié)議的歷史演變和設(shè)計思路”部分


一、HTTP/0.9

最早版本是1991年發(fā)布的0.9版。該版本極其簡單,只有一個命令GET。

GET /index.html11

上面命令表示,TCP 連接(connection)建立后,客戶端向服務(wù)器請求(request)網(wǎng)頁index.html。

協(xié)議規(guī)定,服務(wù)器只能回應(yīng)HTML格式的字符串,不能回應(yīng)別的格式。

Hello World11

服務(wù)器發(fā)送完畢,就關(guān)閉TCP連接。

二、HTTP/1.0

2.1 簡介

1996年5月,HTTP/1.0 版本發(fā)布,內(nèi)容大大增加。

首先,任何格式的內(nèi)容都可以發(fā)送。這使得互聯(lián)網(wǎng)不僅可以傳輸文字,還能傳輸圖像、視頻、二進(jìn)制文件。這為互聯(lián)網(wǎng)的大發(fā)展奠定了基礎(chǔ)。

其次,除了GET命令,還引入了POST命令和HEAD命令,豐富了瀏覽器與服務(wù)器的互動手段。

再次,HTTP請求和回應(yīng)的格式也變了。除了數(shù)據(jù)部分,每次通信都必須包括頭信息(HTTP header),用來描述一些元數(shù)據(jù)。

其他的新增功能還包括狀態(tài)碼(status code)、多字符集支持、多部分發(fā)送(multi-part type)、權(quán)限(authorization)、緩存(cache)、內(nèi)容編碼(content encoding)等。

2.2 請求格式

下面是一個1.0版的HTTP請求的例子。

GET / HTTP/1.0User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)Accept: */*11

可以看到,這個格式與0.9版有很大變化。

第一行是請求命令,必須在尾部添加協(xié)議版本(HTTP/1.0)。后面就是多行頭信息,描述客戶端的情況。

2.3 回應(yīng)格式

服務(wù)器的回應(yīng)如下。

HTTP/1.0 200 OK 
Content-Type: text/plainContent-Length: 137582Expires: Thu, 05 Dec 1997 16:00:00 GMTLast-Modified: Wed, 5 August 1996 15:55:28 GMTServer: Apache 0.84Hello World12341234

回應(yīng)的格式是”頭信息 + 一個空行(\r\n) + 數(shù)據(jù)”。其中,第一行是”協(xié)議版本 + 狀態(tài)碼(status code) + 狀態(tài)描述”。

2.4 Content-Type 字段

關(guān)于字符的編碼,1.0版規(guī)定,頭信息必須是 ASCII 碼,后面的數(shù)據(jù)可以是任何格式。因此,服務(wù)器回應(yīng)的時候,必須告訴客戶端,數(shù)據(jù)是什么格式,這就是Content-Type字段的作用。

下面是一些常見的Content-Type字段的值。

text/plaintext/htmltext/css

p_w_picpath/jpeg

p_w_picpath/png

p_w_picpath/svg+xml

audio/mp4

video/mp4application/javascriptapplication/pdfapplication/zipapplication/atom+xml12345678910111213141516171819202122231234567891011121314151617181920212223

這些數(shù)據(jù)類型總稱為MIME type,每個值包括一級類型和二級類型,之間用斜杠分隔。

除了預(yù)定義的類型,廠商也可以自定義類型。

application/vnd.debian.binary-package11

上面的類型表明,發(fā)送的是Debian系統(tǒng)的二進(jìn)制數(shù)據(jù)包。

MIME type還可以在尾部使用分號,添加參數(shù)。

Content-Type: text/html; charset=utf-811

上面的類型表明,發(fā)送的是網(wǎng)頁,而且編碼是UTF-8。

客戶端請求的時候,可以使用Accept字段聲明自己可以接受哪些數(shù)據(jù)格式。

Accept: */*11

上面代碼中,客戶端聲明自己可以接受任何格式的數(shù)據(jù)。

MIME type不僅用在HTTP協(xié)議,還可以用在其他地方,比如HTML網(wǎng)頁。

2.5 Content-Encoding 字段

由于發(fā)送的數(shù)據(jù)可以是任何格式,因此可以把數(shù)據(jù)壓縮后再發(fā)送。Content-Encoding字段說明數(shù)據(jù)的壓縮方法。

Content-Encoding: gzipContent-Encoding: compressContent-Encoding: deflate11

客戶端在請求時,用Accept-Encoding字段說明自己可以接受哪些壓縮方法。

Accept-Encoding: gzip, deflate11

2.6 缺點

HTTP/1.0 版的主要缺點是,每個TCP連接只能發(fā)送一個請求。發(fā)送數(shù)據(jù)完畢,連接就關(guān)閉,如果還要請求其他資源,就必須再新建一個連接。

TCP連接的新建成本很高,因為需要客戶端和服務(wù)器三次握手,并且開始時發(fā)送速率較慢(slow start)。所以,HTTP 1.0版本的性能比較差。隨著網(wǎng)頁加載的外部資源越來越多,這個問題就愈發(fā)突出了。

為了解決這個問題,有些瀏覽器在請求時,用了一個非標(biāo)準(zhǔn)的Connection字段。

Connection: keep-alive11

這個字段要求服務(wù)器不要關(guān)閉TCP連接,以便其他請求復(fù)用。服務(wù)器同樣回應(yīng)這個字段。

Connection: keep-alive11

一個可以復(fù)用的TCP連接就建立了,直到客戶端或服務(wù)器主動關(guān)閉連接。但是,這不是標(biāo)準(zhǔn)字段,不同實現(xiàn)的行為可能不一致,因此不是根本的解決辦法。

三、HTTP/1.1

1997年1月,HTTP/1.1 版本發(fā)布,只比 1.0 版本晚了半年。它進(jìn)一步完善了 HTTP 協(xié)議,一直用到了20年后的今天,直到現(xiàn)在還是最流行的版本。

3.1 持久連接

1.1 版的最大變化,就是引入了持久連接(persistent connection),即TCP連接默認(rèn)不關(guān)閉,可以被多個請求復(fù)用,不用聲明Connection: keep-alive

客戶端和服務(wù)器發(fā)現(xiàn)對方一段時間沒有活動,就可以主動關(guān)閉連接。不過,規(guī)范的做法是,客戶端在最后一個請求時,發(fā)送Connection: close,明確要求服務(wù)器關(guān)閉TCP連接。

Connection: close 
目前,對于同一個域名,大多數(shù)瀏覽器允許同時建立6個持久連接。

3.2 管道機制

1.1 版還引入了管道機制(pipelining),即在同一個TCP連接里面,客戶端可以同時發(fā)送多個請求。這樣就進(jìn)一步改進(jìn)了HTTP協(xié)議的效率。

舉例來說,客戶端需要請求兩個資源。以前的做法是,在同一個TCP連接里面,先發(fā)送A請求,然后等待服務(wù)器做出回應(yīng),收到后再發(fā)出B請求。管道機制則是允許瀏覽器同時發(fā)出A請求和B請求,但是服務(wù)器還是按照順序,先回應(yīng)A請求,完成后再回應(yīng)B請求。

3.3 Content-Length 字段

一個TCP連接現(xiàn)在可以傳送多個回應(yīng),勢必就要有一種機制,區(qū)分?jǐn)?shù)據(jù)包是屬于哪一個回應(yīng)的。這就是Content-length字段的作用,聲明本次回應(yīng)的數(shù)據(jù)長度。

Content-Length: 349511

上面代碼告訴瀏覽器,本次回應(yīng)的長度是3495個字節(jié),后面的字節(jié)就屬于下一個回應(yīng)了。

在1.0版中,Content-Length字段不是必需的,因為瀏覽器發(fā)現(xiàn)服務(wù)器關(guān)閉了TCP連接,就表明收到的數(shù)據(jù)包已經(jīng)全了。

3.4 分塊傳輸編碼

使用Content-Length字段的前提條件是,服務(wù)器發(fā)送回應(yīng)之前,必須知道回應(yīng)的數(shù)據(jù)長度。

對于一些很耗時的動態(tài)操作來說,這意味著,服務(wù)器要等到所有操作完成,才能發(fā)送數(shù)據(jù),顯然這樣的效率不高。更好的處理方法是,產(chǎn)生一塊數(shù)據(jù),就發(fā)送一塊,采用”流模式”(stream)取代”緩存模式”(buffer)。

因此,1.1版規(guī)定可以不使用Content-Length字段,而使用”分塊傳輸編碼”(chunked transfer encoding)。只要請求或回應(yīng)的頭信息有Transfer-Encoding字段,就表明回應(yīng)將由數(shù)量未定的數(shù)據(jù)塊組成。

Transfer-Encoding: chunked 
每個非空的數(shù)據(jù)塊之前,會有一個16進(jìn)制的數(shù)值,表示這個塊的長度。最后是一個大小為0的塊,就表示本次回應(yīng)的數(shù)據(jù)發(fā)送完了。下面是一個例子。

HTTP/1.1 200 OKContent-Type: text/plainTransfer-Encoding: chunked25This is the data in the first chunk1Cand this is the second one3con8sequence01234567891012345678910

3.5 其他功能

1.1版還新增了許多動詞方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。

另外,客戶端請求的頭信息新增了Host字段,用來指定服務(wù)器的域名。

Host: www.example.com11

有了Host字段,就可以將請求發(fā)往同一臺服務(wù)器上的不同網(wǎng)站,為虛擬主機的興起打下了基礎(chǔ)。

3.6 缺點

雖然1.1版允許復(fù)用TCP連接,但是同一個TCP連接里面,所有的數(shù)據(jù)通信是按次序進(jìn)行的。服務(wù)器只有處理完一個回應(yīng),才會進(jìn)行下一個回應(yīng)。要是前面的回應(yīng)特別慢,后面就會有許多請求排隊等著。這稱為”隊頭堵塞”(Head-of-line blocking)。

為了避免這個問題,只有兩種方法:一是減少請求數(shù),二是同時多開持久連接。這導(dǎo)致了很多的網(wǎng)頁優(yōu)化技巧,比如合并腳本和樣式表、將圖片嵌入CSS代碼、域名分片(domain sharding)等等。如果HTTP協(xié)議設(shè)計得更好一些,這些額外的工作是可以避免的。

四、SPDY 協(xié)議

2009年,谷歌公開了自行研發(fā)的 SPDY 協(xié)議,主要解決 HTTP/1.1 效率不高的問題。

這個協(xié)議在Chrome瀏覽器上證明可行以后,就被當(dāng)作 HTTP/2 的基礎(chǔ),主要特性都在 HTTP/2 之中得到繼承。

五、HTTP/2

2015年,HTTP/2 發(fā)布。它不叫 HTTP/2.0,是因為標(biāo)準(zhǔn)委員會不打算再發(fā)布子版本了,下一個新版本將是 HTTP/3。

5.1 二進(jìn)制協(xié)議

HTTP/1.1 版的頭信息肯定是文本(ASCII編碼),數(shù)據(jù)體可以是文本,也可以是二進(jìn)制。HTTP/2 則是一個徹底的二進(jìn)制協(xié)議,頭信息和數(shù)據(jù)體都是二進(jìn)制,并且統(tǒng)稱為”幀”(frame):頭信息幀和數(shù)據(jù)幀。

二進(jìn)制協(xié)議的一個好處是,可以定義額外的幀。HTTP/2 定義了近十種幀,為將來的高級應(yīng)用打好了基礎(chǔ)。如果使用文本實現(xiàn)這種功能,解析數(shù)據(jù)將會變得非常麻煩,二進(jìn)制解析則方便得多。

5.2 多工

HTTP/2 復(fù)用TCP連接,在一個連接里,客戶端和瀏覽器都可以同時發(fā)送多個請求或回應(yīng),而且不用按照順序一一對應(yīng),這樣就避免了”隊頭堵塞”。

舉例來說,在一個TCP連接里面,服務(wù)器同時收到了A請求和B請求,于是先回應(yīng)A請求,結(jié)果發(fā)現(xiàn)處理過程非常耗時,于是就發(fā)送A請求已經(jīng)處理好的部分, 接著回應(yīng)B請求,完成后,再發(fā)送A請求剩下的部分。

這樣雙向的、實時的通信,就叫做多工(Multiplexing)。

5.3 數(shù)據(jù)流

因為 HTTP/2 的數(shù)據(jù)包是不按順序發(fā)送的,同一個連接里面連續(xù)的數(shù)據(jù)包,可能屬于不同的回應(yīng)。因此,必須要對數(shù)據(jù)包做標(biāo)記,指出它屬于哪個回應(yīng)。

HTTP/2 將每個請求或回應(yīng)的所有數(shù)據(jù)包,稱為一個數(shù)據(jù)流(stream)。每個數(shù)據(jù)流都有一個獨一無二的編號。數(shù)據(jù)包發(fā)送的時候,都必須標(biāo)記數(shù)據(jù)流ID,用來區(qū)分它屬于哪個數(shù)據(jù)流。另外還規(guī)定,客戶端發(fā)出的數(shù)據(jù)流,ID一律為奇數(shù),服務(wù)器發(fā)出的,ID為偶數(shù)。

數(shù)據(jù)流發(fā)送到一半的時候,客戶端和服務(wù)器都可以發(fā)送信號(RST_STREAM幀),取消這個數(shù)據(jù)流。1.1版取消數(shù)據(jù)流的唯一方法,就是關(guān)閉TCP連接。這就是說,HTTP/2 可以取消某一次請求,同時保證TCP連接還打開著,可以被其他請求使用。

客戶端還可以指定數(shù)據(jù)流的優(yōu)先級。優(yōu)先級越高,服務(wù)器就會越早回應(yīng)。

5.4 頭信息壓縮

HTTP 協(xié)議不帶有狀態(tài),每次請求都必須附上所有信息。所以,請求的很多字段都是重復(fù)的,比如Cookie和User Agent,一模一樣的內(nèi)容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度。

HTTP/2 
對這一點做了優(yōu)化,引入了頭信息壓縮機制(header compression)。一方面,頭信息使用gzip或compress壓縮后再發(fā)送;另一方面,客戶端和服務(wù)器同時維護(hù)一張頭信息表,所有字段都會存入這個表,生成一個索引號,以后就不發(fā)送同樣字段了,只發(fā)送索引號,這樣就提高速度了。

5.5 服務(wù)器推送

HTTP/2 允許服務(wù)器未經(jīng)請求,主動向客戶端發(fā)送資源,這叫做服務(wù)器推送(server push)。

常見場景是客戶端請求一個網(wǎng)頁,這個網(wǎng)頁里面包含很多靜態(tài)資源。正常情況下,客戶端必須收到網(wǎng)頁后,解析HTML源碼,發(fā)現(xiàn)有靜態(tài)資源,再發(fā)出靜態(tài) 資源請求。其實,服務(wù)器可以預(yù)期到客戶端請求網(wǎng)頁后,很可能會再請求靜態(tài)資源,所以就主動把這些靜態(tài)資源隨著網(wǎng)頁一起發(fā)給客戶端了。


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI