整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          3分鐘帶你明白HTTP(上)

          3分鐘帶你明白HTTP(上)

          到HTTP,相信無論是開發(fā)還是測試都不會(huì)陌生,我們的日常工作中基本上都會(huì)跟它打交道。但是關(guān)于HTTP全部的知識(shí)點(diǎn),你真的了解嗎?這篇就來讓我們好好了解一下HTTP吧。

          HTTP協(xié)議簡介

          HTTP協(xié)議是Hyper Text Transfer Protocol(超文本傳輸協(xié)議)的縮寫,是用于從萬維網(wǎng)(WWW:World Wide Web )服務(wù)器傳輸超文本到本地瀏覽器的傳送協(xié)議。

          • HTTP是基于TCP/IP通信協(xié)議來傳遞數(shù)據(jù)(HTML 文件, 圖片文件, 查詢結(jié)果等)
          • HTTP是一個(gè)應(yīng)用層協(xié)議,由請求和響應(yīng)構(gòu)成,是一個(gè)標(biāo)準(zhǔn)的客戶端服務(wù)器模型。
          • HTTP是一個(gè)無狀態(tài)的協(xié)議。(實(shí)現(xiàn)會(huì)話跟蹤詳見大話Token、Cookie和Session)
          • HTTP協(xié)議通常承載于TCP協(xié)議之上,有時(shí)也承載于TLS或SSL協(xié)議層之上,這個(gè)時(shí)候,就成了我們常說的HTTPS。如下圖

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


          HTTP協(xié)議主要有以下幾個(gè)特點(diǎn):簡單快速(由于HTTP協(xié)議簡單,使得HTTP服務(wù)器的程序規(guī)模小,因而通信速度很快)、靈活(HTTP允許傳輸任意類型的數(shù)據(jù)對象)、無連接(限制每次連接只處理一個(gè)請求)、無狀態(tài)(協(xié)議對于事務(wù)處理沒有記憶能力)、支持B/S及C/S模式。

          http協(xié)議工作流程

          我們從每個(gè)人日常都會(huì)做的一件事情說起吧。當(dāng)我們打開瀏覽器輸入網(wǎng)址到頁面展示到我們面前,究竟發(fā)生了什么呢?

          其實(shí)這就是我們HTTP的一次操作,我們稱為一個(gè)事務(wù),具體流程如下:

          1、用戶在瀏覽器中鍵入需要訪問網(wǎng)頁的URL或者點(diǎn)擊某個(gè)網(wǎng)頁中鏈接,比如https://www.baidu.com;

          2、瀏覽器根據(jù)URL中的域名,通過DNS解析出目標(biāo)網(wǎng)頁的IP地址

          a) 瀏覽器搜索自身的 DNS 緩存。(如果 DNS 緩存中找到百度的 IP 地址,就跳過了接下來查找 IP 地址步驟,直接訪問該 IP 地址。)

          b) 搜索操作系統(tǒng)自身的 DNS 緩存。(瀏覽器沒有找到緩存或者緩存已經(jīng)失效)

          c) 讀取硬盤中的 host 文件,里面記錄著域名到 IP 地址的映射關(guān)系,Mac 電腦 中位于/etc/hosts。(如果前兩步驟都沒有找到)

          d) 瀏覽器向?qū)拵н\(yùn)營商服務(wù)器或者域名服務(wù)器發(fā)起一個(gè) DNS 解析請求

          3、拿到 IP 地址后,瀏覽器就向該 IP 所在的服務(wù)器建立 TCP 連接(即三次握手,參考繞不開的TCP之三次握手)

          4、連接建立起來之后,瀏覽器就可以向服務(wù)器發(fā)起 HTTP 請求了,請求方式的格式為:統(tǒng)一資源標(biāo)識(shí)符(URL)、協(xié)議版本號(hào),后邊是MIME信息包括請求修飾符、客戶機(jī)信息和可內(nèi)容。(這里比如訪問百度首頁,就向服務(wù)器發(fā)起 HTTP 中的 GET請求)

          5、服務(wù)器接到請求后,經(jīng)過后臺(tái)一些處理之后,給予相應(yīng)的響應(yīng)信息,其格式為一個(gè)狀態(tài)行,包括信息的協(xié)議版本號(hào)、一個(gè)成功或錯(cuò)誤的代碼,后邊是MIME信息包括服務(wù)器信息、實(shí)體信息和可能的內(nèi)容。(如果是百度首頁,就可以把完整的 HTML 頁面代碼返回給瀏覽器)

          6、瀏覽器拿到了百度首頁的完整 HTML 頁面代碼,內(nèi)核和 JS 引擎就會(huì)解析和渲染這個(gè)頁面,里面的 JS、CSS、圖片等靜態(tài)資源也通過一個(gè)個(gè) HTTP 請求進(jìn)行加載。

          7、瀏覽器根據(jù)拿到的資源對頁面進(jìn)行渲染,最終把完整的頁面呈現(xiàn)給用戶。

          8、如果瀏覽器沒有后續(xù)的請求,那么就會(huì)跟服務(wù)器端發(fā)起 TCP 斷開(即四次揮手,參考繞不開的TCP之四次揮手)。如果瀏覽器或者服務(wù)器在其頭信息加入了這行代碼:Connection:keep-alive,TCP連接在發(fā)送后將仍然保持打開狀態(tài),于是,瀏覽器可以繼續(xù)通過相同的連接發(fā)送請求。保持連接節(jié)省了為每個(gè)請求建立新連接所需的時(shí)間,還節(jié)約了網(wǎng)絡(luò)帶寬。

          上面就是一整個(gè)HTTP協(xié)議的工作流程,其實(shí)當(dāng)中涉及了其他協(xié)議,通過下圖了解一下各個(gè)協(xié)議各自的職責(zé)吧。

          其中我們提到了Connection:keep-alive,這就不得不說一下長鏈接和短鏈接了。

          短鏈接

          短連接的操作步驟是:建立連接——數(shù)據(jù)傳輸——關(guān)閉連接...建立連接——數(shù)據(jù)傳輸——關(guān)閉連接

          如果客戶請求頻繁,將在TCP的建立和關(guān)閉操作上浪費(fèi)較多時(shí)間和帶寬。


          長鏈接

          在一個(gè)連接上可以連續(xù)發(fā)送多個(gè)數(shù)據(jù)包,在連接保持期間,如果沒有數(shù)據(jù)包發(fā)送,需要雙方發(fā)鏈路檢測包。

          長鏈接操作步驟:建立連接——數(shù)據(jù)傳輸...(保持連接)...數(shù)據(jù)傳輸——關(guān)閉連接

          長連接可以省去較多的TCP建立和關(guān)閉的操作,減少浪費(fèi),節(jié)約時(shí)間

          URL、URN和URI

          URI,是uniform resource identifier,統(tǒng)一資源標(biāo)識(shí)符,用來唯一標(biāo)識(shí)一個(gè)資源。

          Web上可用的每種資源如HTML文檔、圖像、視頻片段、程序等都是一個(gè)來URI來定位的

          URI一般由三部組成:訪問資源的命名機(jī)制、存放資源的主機(jī)名、資源自身的名稱,由路徑表示,著重強(qiáng)調(diào)于資源。

          URL是uniform resource locator,統(tǒng)一資源定位器,它是一種具體的URI,即URL可以用來標(biāo)識(shí)一個(gè)資源,而且還指明了如何locate這個(gè)資源。

          URL是Internet上用來描述信息資源的字符串,主要用在各種WWW客戶程序和服務(wù)器程序上。

          采用URL可以用一種統(tǒng)一的格式來描述各種信息資源,包括文件、服務(wù)器的地址和目錄等。URL一般由三部組成:協(xié)議(或稱為服務(wù)方式)、存有該資源的主機(jī)IP地址(有時(shí)也包括端口號(hào))、主機(jī)資源的具體地址,如目錄和文件名等。

          URN,uniform resource name,統(tǒng)一資源命名,是通過名字來標(biāo)識(shí)資源。

          URI是以一種抽象的,高層次概念定義統(tǒng)一資源標(biāo)識(shí),而URL和URN則是具體的資源標(biāo)識(shí)的方式。URL和URN都是一種URI?;\統(tǒng)地說,每個(gè) URL 都是 URI,但不一定每個(gè) URI 都是 URL。這是因?yàn)?URI 還包括一個(gè)子類,即統(tǒng)一資源名稱 (URN),它命名資源但不指定如何定位資源。

          在Java的URI中,一個(gè)URI實(shí)例可以代表絕對的,也可以是相對的,只要它符合URI的語法規(guī)則。而URL類則不僅符合語義,還包含了定位該資源的信息,因此它不能是相對的。

          在Java類庫中,URI類不包含任何訪問資源的方法,它唯一的作用就是解析。

          相反的是,URL類可以打開一個(gè)到達(dá)資源的流。

          以上我們僅僅對HTTP部分概念做了解釋,還有很多面試和工作中會(huì)遇到的HTTP相關(guān)知識(shí)待解釋,讓我們留在下篇文章,不見不散好嘛~

          個(gè)時(shí)代,都不會(huì)虧待會(huì)學(xué)習(xí)的人。

          大家好,我是 yes。

          HTTP 協(xié)議在當(dāng)今的互聯(lián)網(wǎng)可謂是隨處可見,一直默默的在背后支持著網(wǎng)絡(luò)世界的運(yùn)行,對于我們程序員來說 HTTP 更是熟悉不過。

          平日里我們都說架構(gòu)是演進(jìn)的,需求推動(dòng)著技術(shù)的迭代、更新和進(jìn)步,對于 HTTP 協(xié)議來說也是如此。

          不知你是否有想過 HTTP 協(xié)議是如何誕生的,一開始是怎樣的,又是怎么一步一步發(fā)展到今天的 HTTP/3 ?

          其中經(jīng)歷了哪些不為人知的秘密?

          今天我就想和大家一起來看一看 HTTP 的演進(jìn)之路,來看看它是如何從一個(gè)小寶寶成長為現(xiàn)在統(tǒng)治互聯(lián)網(wǎng)的存在。

          不過在此之前,我們先簡單的看看互聯(lián)網(wǎng)的始祖-阿帕網(wǎng)的一段小歷史,還是很有趣的。

          互聯(lián)網(wǎng)的始祖-阿帕網(wǎng)

          在 1950 年代,通信研究者們認(rèn)識(shí)到不同計(jì)算機(jī)用戶和網(wǎng)絡(luò)之間的需要通信,這促使了分布式網(wǎng)絡(luò)、排隊(duì)論和封包交互的研究。

          在1958 年2月7日,美國國防部長尼爾 · 麥克爾羅伊發(fā)布了國防部 5105.15 號(hào)指令,建立了高級(jí)研究計(jì)劃局(ARPA) 。


          ARPA 的核心機(jī)構(gòu)之一 IPTO(信息處理處)贊助的一項(xiàng)研究導(dǎo)致了阿帕網(wǎng)的開發(fā)。

          我們來看看這段歷史。

          在 1962 年,ARPA 的主任聘請約瑟夫·利克萊德?lián)?IPTO 的第一任主任,他是最早預(yù)見到現(xiàn)代交互計(jì)算及其在各種應(yīng)用的人之一。

          IPTO 資助了先進(jìn)的計(jì)算機(jī)和網(wǎng)絡(luò)技術(shù)的研究,并委托十三個(gè)研究小組對人機(jī)交互和分布式系統(tǒng)相關(guān)技術(shù)進(jìn)行研究。每個(gè)小組獲得的預(yù)算是正常研究補(bǔ)助金的三十至四十倍。

          這就是財(cái)大氣粗啊,研究人員肯定是干勁十足!

          在 1963 年利克萊德資助了一個(gè)名為 MAC 的研究項(xiàng)目,該項(xiàng)目旨在探索在分時(shí)計(jì)算機(jī)上建立社區(qū)的可能性

          這個(gè)項(xiàng)目對 IPTO 和更廣泛的研究界產(chǎn)生了持久的影響,成為廣泛聯(lián)網(wǎng)的原型。

          并且利克萊德的全球網(wǎng)絡(luò)愿景極大地影響了他在 IPTO 的繼任者們。

          1964 年利克萊德跳槽到了 IBM,第二任主任薩瑟蘭上線,他創(chuàng)建了革命性的 Sketchpad 程序,用于存儲(chǔ)計(jì)算機(jī)顯示器的內(nèi)存,在 1965 年他與麻省理工學(xué)院的勞倫斯 · 羅伯茨簽訂了 IPTO 合同,以進(jìn)一步發(fā)展計(jì)算機(jī)網(wǎng)絡(luò)技術(shù)。

          隨后,羅伯茨和托馬斯 · 梅里爾在麻省理工學(xué)院的 TX-2 計(jì)算機(jī)和加利福尼亞的 Q-32 計(jì)算機(jī)之間,通過撥號(hào)電話連接實(shí)現(xiàn)了第一個(gè)數(shù)據(jù)包交換。

          1966 年第三任主任鮑勃 · 泰勒上任,他深受利克萊德的影響,巧的是泰勒和利克萊德一樣也是個(gè)心理聲學(xué)家。


          在泰勒的 IPTO 辦公室里有三個(gè)不同的終端連接到三個(gè)不同的研究站點(diǎn),他意識(shí)到這種架構(gòu)將嚴(yán)重限制他擴(kuò)展訪問多個(gè)站點(diǎn)的能力。

          于是他想著把一個(gè)終端連接到一個(gè)可以訪問多個(gè)站點(diǎn)的網(wǎng)絡(luò)上,并且從他在五角大樓的職位來說,他有這個(gè)能力去實(shí)現(xiàn)這個(gè)愿景。

          美國國防部高級(jí)研究計(jì)劃局局長查理 · 赫茨菲爾德向泰勒承諾,如果 IPTO 能夠組織起來,他將提供 100 萬美元用于建立一個(gè)分布式通信網(wǎng)絡(luò)。

          泰勒一聽舒服了,然后他對羅伯茨的工作印象很深刻,邀請他加入并領(lǐng)導(dǎo)這項(xiàng)工作,然后羅伯茨卻不樂意。

          泰勒不高興了,于是要求赫茨菲爾德讓林肯實(shí)驗(yàn)室的主任向羅伯茨施壓,要求他重新考慮,這最終促使羅伯茨緩和了態(tài)度,于1966年12月加入 IPTO 擔(dān)任首席科學(xué)家。


          在 1968 年6月3日,羅伯茨向泰勒描述了建立阿帕網(wǎng)的計(jì)劃,18 天后,也就是 6 月 21 日,泰勒批準(zhǔn)了這個(gè)計(jì)劃,14 個(gè)月后阿帕網(wǎng)建立

          當(dāng)阿帕網(wǎng)順利發(fā)展時(shí),泰勒于 1969 年9月將 IPTO 的管理權(quán)移交給羅伯茨。

          隨后羅伯茨離開 ARPA 成為 Telenet 的 CEO ,而利克萊德再次回到 IPTO 擔(dān)任董事,以完成該組織的生命周期。

          至此,這段歷史暫告一段落,可以看到阿帕網(wǎng)之父羅伯茨還是被施壓的才接受這項(xiàng)任務(wù),最終創(chuàng)建了阿帕網(wǎng),互聯(lián)網(wǎng)的始祖

          也多虧了利克萊德的遠(yuǎn)見和砸錢促進(jìn)了技術(shù)的發(fā)展,ARPA 不僅成為網(wǎng)絡(luò)誕生地,同樣也是電腦圖形、平行過程、計(jì)算機(jī)模擬飛行等重要成果的誕生地。

          歷史就是這么的巧合和有趣。

          互聯(lián)網(wǎng)的歷史

          在 1973 年 ARPA 網(wǎng)擴(kuò)展成互聯(lián)網(wǎng),第一批接入的有英國和挪威計(jì)算機(jī),逐漸地成為網(wǎng)絡(luò)連接的骨干。

          1974 年 ARPA 的羅伯特·卡恩和斯坦福的文頓·瑟夫提出TCP/IP 協(xié)議。

          1986 年,美國國家科學(xué)基金會(huì)(National Science Foundation,NSF)建立了大學(xué)之間互聯(lián)的骨干網(wǎng)絡(luò) NSFNET ,這是互聯(lián)網(wǎng)歷史上重要的一步,NSFNET 成為新的骨干,1990 年 ARPANET 退役。

          在 1990 年 ,蒂姆·伯納斯-李(下文我就稱李老) 創(chuàng)建了運(yùn)行萬維網(wǎng)所需的所有工具:超文本傳輸協(xié)議(HTTP)、超文本標(biāo)記語言(HTML)、第一個(gè)網(wǎng)頁瀏覽器、第一個(gè)網(wǎng)頁服務(wù)器和第一個(gè)網(wǎng)站。


          至此,互聯(lián)網(wǎng)開啟了快速發(fā)展之路,HTTP 也開始了它的偉大征途。

          還有很多有趣的歷史,比如第一次瀏覽器大戰(zhàn)等等,之后有機(jī)會(huì)再談,今天我們的主角是 HTTP。

          接下來我們就看看 HTTP 各大版本的演進(jìn),來看看它是如何成長到今天這個(gè)樣子的。

          HTTP / 0.9 時(shí)代

          在 1989 年,李老發(fā)表了一篇論文,文中提出了三項(xiàng)現(xiàn)在看來很平常的三個(gè)概念。

          • URI,統(tǒng)一資源標(biāo)識(shí)符,作為互聯(lián)網(wǎng)上的唯一標(biāo)識(shí)。
          • HTML,超文本標(biāo)記語言,描述超文本。
          • HTTP ,超文本傳輸協(xié)議,傳輸超文本。

          隨后李老就付之于行動(dòng),把這些都搞出來了,稱之為萬維網(wǎng)(World Wide Web)。

          那時(shí)候是互聯(lián)網(wǎng)初期,計(jì)算機(jī)的處理能力包括網(wǎng)速等等都很弱,所以 HTTP 也逃脫不了那個(gè)時(shí)代的約束,因此設(shè)計(jì)的非常簡單,而且也是純文本格式。

          李老當(dāng)時(shí)的想法是文檔存在服務(wù)器里面,我們只需要從服務(wù)器獲取文檔,因此只有 “GET”,也不需要啥請求頭,并且拿完了就結(jié)束了,因此請求響應(yīng)之后連接就斷了

          這就是為什么 HTTP 設(shè)計(jì)為文本協(xié)議,并且一開始只有“GET”、響應(yīng)之后連接就斷了的原因了。

          在我們現(xiàn)在看來這協(xié)議太簡陋了,但是在當(dāng)時(shí)這是互聯(lián)網(wǎng)發(fā)展的一大步!一個(gè)東西從無到有是最困難的。

          這時(shí)候的 HTTP 還沒有版本號(hào)的,之所以稱之為 HTTP / 0.9 是后人加上去了,為了區(qū)別之后的版本。

          HTTP 1.0 時(shí)代

          人們的需求是無止盡的,隨著圖像和音頻的發(fā)展,瀏覽器也在不斷的進(jìn)步予以支持。

          在 1995 年又開發(fā)出了 Apache,簡化了 HTTP 服務(wù)器的搭建,越來越多的人用上了互聯(lián)網(wǎng),這也促進(jìn)了 HTTP 協(xié)議的修改。

          需求促使添加各種特性來滿足用戶的需求,經(jīng)過了一系列的草案 HTTP/1.0 于 1996 年正式發(fā)布。

          Dave Raggett 在1995年領(lǐng)導(dǎo)了 HTTP 工作組,他希望通過擴(kuò)展操作、擴(kuò)展協(xié)商、更豐富的元信息以及與安全協(xié)議相關(guān)的安全協(xié)議來擴(kuò)展協(xié)議,這種安全協(xié)議通過添加額外的方法和頭字段來提高效率。


          所以在 HTTP/1.0 版本主要增加以下幾點(diǎn):

          • 增加了 HEAD、POST 等新方法。
          • 增加了響應(yīng)狀態(tài)碼。
          • 引入了頭部,即請求頭和響應(yīng)頭。
          • 在請求中加入了 HTTP 版本號(hào)。
          • 引入了 Content-Type ,使得傳輸?shù)臄?shù)據(jù)不再限于文本。

          可以看到引入了新的方法,填充了操作的語義,像 HEAD 還可以只拿元信息不必傳輸全部內(nèi)容,提高某些場景下的效率。

          引入的響應(yīng)狀態(tài)碼讓請求方可以得知服務(wù)端的情況,可以區(qū)分請求出錯(cuò)的原因,不會(huì)一頭霧水。

          引入了頭部,使得請求和響應(yīng)更加的靈活,把控制數(shù)據(jù)和業(yè)務(wù)實(shí)體進(jìn)行了拆分,也是一種解耦。

          新增了版本號(hào)表明這是一種工程化的象征,說明走上了正途,畢竟沒版本號(hào)無法管理。

          引入了 Content-Type,支持傳輸不同類型的數(shù)據(jù),豐富了協(xié)議的載體,充實(shí)了用戶的眼球。

          但是那時(shí)候 HTTP/1.0 還不是標(biāo)準(zhǔn),沒有實(shí)際的約束力,各方勢力不吃這一套,大白話就是你算老幾。

          HTTP 1.1 時(shí)代

          HTTP/1.1 版本在 1997 的 RFC 2068 中首次被記錄,從 1995 年至 1999 年間的第一次瀏覽器大戰(zhàn),極大的推動(dòng)了 Web 的發(fā)展。

          隨著發(fā)展 HTTP/1.0 演進(jìn)成了 HTTP/1.1,并且在 1999 年廢棄了之前的 RFC 2068,發(fā)布了 RFC 2616。

          從版本號(hào)可以得知這是一個(gè)小版本的更新,更新主要是因?yàn)?HTTP/1.0 很大的性能問題,就是每請求一個(gè)資源都得新建一個(gè) TCP 連接,而且只能串行請求。

          所以在 HTTP/1.1 版本主要增加以下幾點(diǎn):

          • 新增了連接管理即 keepalive ,允許持久連接。
          • 支持 pipeline,無需等待前面的請求響應(yīng),即可發(fā)送第二次請求。
          • 允許響應(yīng)數(shù)據(jù)分塊(chunked),即響應(yīng)的時(shí)候不標(biāo)明Content-Length,客戶端就無法斷開連接,直到收到服務(wù)端的 EOF ,利于傳輸大文件。
          • 新增緩存的控制和管理。
          • 加入了 Host 頭,用在你一臺(tái)機(jī)子部署了多個(gè)主機(jī),然后多個(gè)域名解析又是同一個(gè) IP,此時(shí)加入了 Host 頭就可以判斷你到底是要訪問哪個(gè)主機(jī)。


          可以看到瀏覽器大戰(zhàn)推進(jìn)了 Web 的發(fā)展,也暴露出 HTTP/1.0 的不足之處,畢竟網(wǎng)絡(luò)帶寬等等都在進(jìn)步,總不能讓協(xié)議限制了硬件的發(fā)展。

          因此提出了 HTTP/1.1 ,主要是為了解決性能的問題,包括支持持久連接、pipeline、緩存管理等等,也添加了一些特性。

          再后來到 2014 年對 HTTP/1.1 又做了一次修訂,因?yàn)槠涮^龐大和復(fù)雜,因此進(jìn)行了拆分,弄成了六份小文檔 RFC7230 - RFC7235

          這時(shí)候 HTTP/1.1 已經(jīng)成了標(biāo)準(zhǔn),其實(shí)標(biāo)準(zhǔn)往往是在各大強(qiáng)力競爭對手相對穩(wěn)定之后建立的,因?yàn)闃?biāo)準(zhǔn)意味著統(tǒng)一,統(tǒng)一就不用費(fèi)勁心思去兼容各種玩意。

          只有強(qiáng)大的勢力才能定標(biāo)準(zhǔn),當(dāng)你足夠強(qiáng)大的時(shí)候你也可以定標(biāo)準(zhǔn),去挑戰(zhàn)老標(biāo)準(zhǔn)。

          HTTP 2 時(shí)代

          隨著 HTTP/1.1 的發(fā)布,互聯(lián)網(wǎng)也開始了爆發(fā)式的增長,這種增長暴露出 HTTP 的不足,主要還是性能問題,而 HTTP/1.1 無動(dòng)于衷。

          這就是人的惰性,也符合平日里我們對產(chǎn)品的演進(jìn),當(dāng)你足夠強(qiáng)大又安逸的時(shí)候,任何的改動(dòng)你是不想理會(huì)的。

          別用咯。


          這時(shí)候 Google 看不下去了,你不搞是吧?我自己搞我的,我自己和我自己玩,我用戶群體大,我有 Chrome,我服務(wù)多了去了。

          Google 推出了 SPDY 協(xié)議,憑借著它全球的占有率超過了 60% 的底氣,2012年7月,開發(fā) SPDY 的小組公開表示,它正在努力實(shí)現(xiàn)標(biāo)準(zhǔn)化。

          HTTP 坐不住了,之后互聯(lián)網(wǎng)標(biāo)準(zhǔn)化組織以 SPDY 為基礎(chǔ)開始制定新版本的 HTTP 協(xié)議,最終在 2015 年發(fā)布了 HTTP/2。

          HTTP/2 版本主要增加以下幾點(diǎn):

          • 是二進(jìn)制協(xié)議,不再是純文本。
          • 支持一個(gè) TCP 連接發(fā)起多請求,移除了 pipeline。
          • 利用 HPACK 壓縮頭部,減少數(shù)據(jù)傳輸量。
          • 允許服務(wù)端主動(dòng)推送數(shù)據(jù)。

          從文本到二進(jìn)制其實(shí)簡化了整齊的復(fù)雜性,解析數(shù)據(jù)的開銷更小,數(shù)據(jù)更加緊湊,減少了網(wǎng)絡(luò)的延遲,提升了整體的吞吐量。


          支持一個(gè) TCP 連接發(fā)起多請求,即支持多路復(fù)用,像 HTTP/1.1 pipeline 還是有阻塞的情況,需要等前面的一個(gè)響應(yīng)返回了后面的才能返回。

          而多路復(fù)用就是完全異步化,這減少了整體的往返時(shí)間(RTT),解決了 HTTP 隊(duì)頭阻塞問題,也規(guī)避了 TCP 慢啟動(dòng)帶來的影響

          HPACK 壓縮頭部,采用了靜態(tài)表、動(dòng)態(tài)表和哈夫曼編碼,在客戶端和服務(wù)器都維護(hù)請求頭的列表,所以只需要增量和壓縮過的頭部信息,服務(wù)端拿到之后組裝一下就能得到完整的頭部信息。

          形象一點(diǎn)就是如下圖所示:


          再具體一點(diǎn)就是下圖這樣:


          服務(wù)端主動(dòng)推送數(shù)據(jù),這個(gè)其實(shí)就是減少了請求的次數(shù),比如客戶端請求 1.html,我把 1.html 需要的 js 和 css 也一塊送過去,省的之后客戶端再請求我要 js ,我要這個(gè) css。

          可以看到 HTTP/2 的整體演進(jìn)都是往性能優(yōu)化的角度發(fā)展,因?yàn)榇藭r(shí)的性能就是痛點(diǎn),任何東西的演進(jìn)都是哪里痛醫(yī)哪里。

          當(dāng)然有一些例外,比如一些意外,或者就是“閑的蛋疼”的那種捯飭。

          這次推進(jìn)屬于用戶揭竿而起為之,你再不給我升級(jí)我自己搞了,我有著資本,你自己掂量。

          最終結(jié)果是好的,Google 后來放棄了 SPDY ,擁抱標(biāo)準(zhǔn),而 HTTP/1.1 這個(gè)歷史包袱太重了,所以 HTTP/2 到現(xiàn)在也只有大致一半的網(wǎng)站使用它。


          HTTP 3 時(shí)代

          這 HTTP/2 還沒捂熱, HTTP/3 怎么就來了?

          這次又是 Google,它自己突破自己,主要也是源自于痛點(diǎn),這次的痛點(diǎn)來自于 HTTP 依賴的 TCP。

          TCP 是面向可靠的、有序的傳輸協(xié)議,因此會(huì)有失敗重傳和按序機(jī)制,而 HTTP/2 是所有流共享一個(gè) TCP 連接,所以會(huì)有 TCP 層面的隊(duì)頭阻塞,當(dāng)發(fā)生重傳時(shí)會(huì)影響多個(gè)請求響應(yīng)。

          并且 TCP 是基于四元組(源IP,源端口,目標(biāo)IP,目標(biāo)端口)來確定連接的,而在移動(dòng)網(wǎng)絡(luò)的情況下 IP 地址會(huì)頻繁的換,這會(huì)導(dǎo)致反復(fù)的建連。

          還有 TCP 與 TLS 的疊加握手,增加了延時(shí)。

          問題就出在 TCP 身上,所以 Google 就把目光瞄向了 UDP。

          UDP 我們知道是無連接的,不管什么順序,也不管你什么丟包,而 TCP 我在之前的文章說的很清楚了TCP疑難雜癥解析不了解的同學(xué)可以去看看。

          簡單的說就是 TCP 太無私了,或者說太保守了,現(xiàn)在需要一種更激進(jìn)的做法。

          那怎么搞? TCP 改不動(dòng)我就換!然后把 TCP 可靠、有序的功能提到應(yīng)用層來實(shí)現(xiàn),因此 Google 就研究出了 QUIC 協(xié)議。


          QUIC 層來實(shí)現(xiàn)自己的丟包重傳和擁塞控制,還有出于安全的考慮我們都會(huì)用 HTTPS ,所以需要多次握手。


          上面我也已經(jīng)提到了關(guān)于四元組的情況,所以在移動(dòng)互聯(lián)網(wǎng)時(shí)代這握手的消耗就更加放大了,于是 QUIC 引入了個(gè)叫 Connection ID 來標(biāo)識(shí)一個(gè)鏈接,所以切換網(wǎng)絡(luò)之后可以復(fù)用這個(gè)連接,達(dá)到 0 RTT 就能開始傳輸。


          注意上圖是在已經(jīng)和服務(wù)端握過手之后的,由于網(wǎng)絡(luò)切換等原因才有 0 RTT ,也就是 Connection ID 在之前生成過了

          如果是第一次建連還是需要多次握手的,我們來看一下簡化的握手對比圖。


          所以所謂的 0RTT 是在之前已經(jīng)建連的情況下。

          當(dāng)然還有 HTTP/2 提到的 HPACK,這個(gè)是依賴 TCP 的可靠、有序傳輸?shù)?,于?QUIC 得搞了個(gè) QPACK,也采用了靜態(tài)表、動(dòng)態(tài)表和哈夫曼編碼。

          它豐富了 HTTP/2 的靜態(tài)表,從 61 項(xiàng)加到了 98 項(xiàng)。

          上面提到的動(dòng)態(tài)表,是用來存儲(chǔ)未包含在靜態(tài)表中的頭部項(xiàng),假設(shè)動(dòng)態(tài)表還未收到,后面來解頭部的時(shí)候肯定要被阻塞的。

          所以 QPACK 就另開一條路,在單向的 Stream 里傳輸動(dòng)態(tài)表的編解碼,單向傳輸好了,接受端到才能開始解碼,也就是說還沒好你就先別管,防止做一半卡住了

          那還有前面提到的 TCP 隊(duì)頭阻塞, QUIC 是怎么解決的呢?畢竟它也要保證有序和可靠啊。

          因?yàn)?TCP 不認(rèn)識(shí)每個(gè)流分別是哪個(gè)請求的,所以它只能全部阻塞住,而 QUIC 知道,因此比如請求 A 丟包了,我就把 A 卡住了就行,請求 B 完全可以全部放行,絲毫不受影響。

          可以看到基于 UDP 的 QUIC 還是很強(qiáng)大的,而且人家用戶多,在 2018 年,互聯(lián)網(wǎng)標(biāo)準(zhǔn)化組織 IETF 提議將 HTTP over QUIC 更名為 HTTP/3 并獲得批準(zhǔn)

          可以看到需求又推動(dòng)技術(shù)的進(jìn)步,由于 TCP 自身機(jī)制的限制,我們的目光已經(jīng)往 UDP 上靠了,那 TCP 會(huì)不會(huì)成為歷史呢?

          我們拭目以待。

          最后

          今天我們大致過了一遍 HTTP 發(fā)展的歷史和它的演進(jìn)之路,可以看到技術(shù)是源于需求,需求推動(dòng)著技術(shù)的發(fā)展。

          本質(zhì)上就是人的惰性,只有痛了才會(huì)成長。

          而且標(biāo)準(zhǔn)其實(shí)也是巨頭們?yōu)榱怂麄兊睦嫱苿?dòng)的,不過標(biāo)準(zhǔn)確實(shí)能減輕對接的開銷,統(tǒng)一而方便。

          當(dāng)然就 HTTP 來說還是有很多內(nèi)容的,有很多細(xì)節(jié),很多算法,比如拿 Connection ID 來說,不同的四元組你如何保證請求一定會(huì)轉(zhuǎn)發(fā)到之前的服務(wù)器上?

          所以今天我只是淺顯的談了談大致的演進(jìn),具體的實(shí)現(xiàn)還是得靠各位自己摸索,或者之后有機(jī)會(huì)我再寫一些。

          不過相對于這些實(shí)現(xiàn)細(xì)節(jié)我更感興趣的是歷史的演進(jìn),這能讓我從時(shí)代背景等一些約束來得知,為什么這東西一開始是這么設(shè)計(jì)的,從而更深刻的理解這玩意。

          而且歷史還是很有趣的,不是么?


          我是 yes,從一點(diǎn)點(diǎn)到億點(diǎn)點(diǎn),我們下篇見

          巨人的肩膀

          https://www.livinginternet.com/i/ii_ipto.htm

          https://jacobianengineering.com/blog/2016/11/1543/

          https://w3techs.com/technologies/details/ce-http2

          https://www.verizondigitalmedia.com/blog/how-quic-speeds-up-all-web-applications/

          https://www.oreilly.com/content/http2-a-new-excerpt/

          https://www.darpa.mil/about-us/timeline/dod-establishes-arpa

          https://en.wikipedia.org/wiki/ARPANET

          https://en.wikipedia.org/wiki/Internet

          深入剖析HTTP/3協(xié)議 ,陶輝

          透視HTTP協(xié)議 ,羅劍鋒

          、HTTP簡介

          HTTP協(xié)議是Hyper Text Transfer Protocol(超文本傳輸協(xié)議)的縮寫,“超文本”即不僅僅是文本,還可以傳輸HTML 文件, 圖片文件等。

          HTTP協(xié)議工作于客戶端-服務(wù)端架構(gòu)為上。瀏覽器作為HTTP客戶端通過URL向HTTP服務(wù)端即WEB服務(wù)器發(fā)送所有請求。Web服務(wù)器根據(jù)接收到的請求后,向客戶端發(fā)送響應(yīng)信息。

          二、主要特點(diǎn)

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

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

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

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

          支持B/S及C/S模式。

          三、基礎(chǔ)概念

          URL

          URI 包含 URL 和 URN,目前 WEB 只有 URL 比較流行,所以見到的基本都是 URL。

          URI(Uniform Resource Identifier,統(tǒng)一資源標(biāo)識(shí)符)

          URL(Uniform Resource Locator,統(tǒng)一資源定位符)

          URN(Uniform Resource Name,統(tǒng)一資源名稱)

          三者的區(qū)別

          URI用來唯一的標(biāo)識(shí)一個(gè)資源。Web上可用的每種資源如HTML文檔、圖像、視頻片段、程序等都是一個(gè)來URI來標(biāo)識(shí)的。URI一般由三部組成: ①訪問資源的命名機(jī)制 ②存放資源的主機(jī)名 ③資源自身的名稱,由路徑表示,著重強(qiáng)調(diào)于資源。

          URL是一種具體的URI,即URL可以用來標(biāo)識(shí)一個(gè)資源,而且還指明了如何locate這個(gè)資源。采用URL可以用一種統(tǒng)一的格式來描述各種信息資源,包括文件、服務(wù)器的地址和目錄等。URL一般由三部組成: ①協(xié)議(或稱為服務(wù)方式) ②存有該資源的主機(jī)IP地址(有時(shí)也包括端口號(hào)) ③主機(jī)資源的具體地址。如目錄和文件名等

          URN是通過名字來標(biāo)識(shí)資源,比如mailto:java-net@java.sun.com。

          一個(gè)URL的例子

          http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name

          從上面的URL可以看出,一個(gè)完整的URL包括以下幾部分:

          1.協(xié)議部分: 該URL的協(xié)議部分為“http:”,這代表網(wǎng)頁使用的是HTTP協(xié)議。在Internet中可以使用多種協(xié)議,如HTTP,F(xiàn)TP等等本例中使用的是HTTP協(xié)議。在"HTTP"后面的“//”為分隔符

          2.域名部分: 該URL的域名部分為“www.aspxfans.com”。一個(gè)URL中,也可以使用IP地址作為域名使用

          3.端口部分: 跟在域名后面的是端口,域名和端口之間使用“:”作為分隔符。端口不是一個(gè)URL必須的部分,如果省略端口部分,將采用默認(rèn)端口

          4.虛擬目錄部分: 從域名后的第一個(gè)“/”開始到最后一個(gè)“/”為止,是虛擬目錄部分。虛擬目錄也不是一個(gè)URL必須的部分。本例中的虛擬目錄是“/news/”

          5.文件名部分: 從域名后的最后一個(gè)“/”開始到“?”為止,是文件名部分,如果沒有“?”,則是從域名后的最后一個(gè)“/”開始到“#”為止,是文件部分,如果沒有“?”和“#”,那么從域名后的最后一個(gè)“/”開始到結(jié)束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一個(gè)URL必須的部分,如果省略該部分,則使用默認(rèn)的文件名

          6.錨部分: 從“#”開始到最后,都是錨部分。本例中的錨部分是“name”。錨部分也不是一個(gè)URL必須的部分

          7.參數(shù)部分: 從“?”開始到“#”為止之間的部分為參數(shù)部分,又稱搜索部分、查詢部分。本例中的參數(shù)部分為“boardID=5&ID=24618&page=1”。參數(shù)可以允許有多個(gè)參數(shù),參數(shù)與參數(shù)之間用“&”作為分隔符。

          請求和響應(yīng)報(bào)文

          1. 請求報(bào)文

          請求報(bào)文由請求行(request line)、請求頭部(header)、空行和請求數(shù)據(jù)四個(gè)部分組成。

          第一部分:請求行,用來說明請求類型,要訪問的資源以及所使用的HTTP版本

          GET說明請求類型為GET,[/562f25980001b1b106000338.jpg]為要訪問的資源,該行的最后一部分說明使用的是HTTP1.1版本。

          第二部分:請求頭部,緊接著請求行(即第一行)之后的部分,用來說明服務(wù)器要使用的附加信息

          從第二行起為請求頭部,HOST將指出請求的目的地.User-Agent,服務(wù)器端和客戶端腳本都能訪問它,它是瀏覽器類型檢測邏輯的重要基礎(chǔ).該信息由你的瀏覽器來定義,并且在每個(gè)請求中自動(dòng)發(fā)送等等

          第三部分:空行,請求頭部后面的空行是必須的

          即使第四部分的請求數(shù)據(jù)為空,也必須有空行

          第四部分:請求數(shù)據(jù)也叫主體,可以添加任意的其他數(shù)據(jù)

          2. 響應(yīng)報(bào)文

          HTTP響應(yīng)也由四個(gè)部分組成,分別是:狀態(tài)行、消息報(bào)頭、空行和響應(yīng)正文。

          第一部分:狀態(tài)行,由HTTP協(xié)議版本號(hào), 狀態(tài)碼, 狀態(tài)消息 三部分組成。

          第一行為狀態(tài)行,(HTTP/1.1)表明HTTP版本為1.1版本,狀態(tài)碼為200,狀態(tài)消息為(ok)

          第二部分:消息報(bào)頭,用來說明客戶端要使用的一些附加信息

          第二行和第三行為消息報(bào)頭, Date:生成響應(yīng)的日期和時(shí)間;Content-Type:指定了MIME類型的HTML(text/html),編碼類型是UTF-8

          第三部分:空行,消息報(bào)頭后面的空行是必須的

          第四部分:響應(yīng)正文,服務(wù)器返回給客戶端的文本信息。

          空行后面的html部分為響應(yīng)正文。

          四、HTTP 方法

          根據(jù)HTTP標(biāo)準(zhǔn),HTTP請求可以使用多種請求方法。HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法。HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。后來又引入了PATCH方法,是對PUT方法的補(bǔ)充。

          GET

          請求指定的頁面信息,并返回實(shí)體主體。

          HEAD

          類似于get請求,只不過返回的響應(yīng)中沒有具體的內(nèi)容,用于獲取報(bào)頭。主要用于確認(rèn) URL 的有效性以及資源更新的日期時(shí)間等。

          POST

          POST 主要用來傳輸數(shù)據(jù),而 GET 主要用來獲取資源。POST請求可能會(huì)導(dǎo)致新的資源的建立和/或已有資源的修改。

          PUT

          從客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定的文檔的內(nèi)容。由于自身不帶驗(yàn)證機(jī)制,任何人都可以上傳文件,因此存在安全性問題,一般不使用該方法。

          DELETE

          請求服務(wù)器刪除指定的頁面。與 PUT 功能相反,并且同樣不帶驗(yàn)證機(jī)制。

          CONNECT

          要求在與代理服務(wù)器通信時(shí)建立隧道

          使用 SSL(Secure Sockets Layer,安全套接層)和 TLS(Transport Layer Security,傳輸層安全)協(xié)議把通信內(nèi)容加密后經(jīng)網(wǎng)絡(luò)隧道傳輸。

          CONNECT www.example.com:443 HTTP/1.1

          OPTIONS

          查詢支持的方法

          查詢指定的 URL 能夠支持的方法。

          會(huì)返回 Allow: GET, POST, HEAD, OPTIONS 這樣的內(nèi)容。

          TRACE

          追蹤路徑

          服務(wù)器會(huì)將通信路徑返回給客戶端。

          發(fā)送請求時(shí),在 Max-Forwards 首部字段中填入數(shù)值,每經(jīng)過一個(gè)服務(wù)器就會(huì)減 1,當(dāng)數(shù)值為 0 時(shí)就停止傳輸。

          通常不會(huì)使用 TRACE,并且它容易受到 XST 攻擊(Cross-Site Tracing,跨站追蹤)。主要用于測試或診斷。

          PATCH

          對資源進(jìn)行部分修改

          PUT 也可以用于修改資源,但是只能完全替代原始資源,PATCH 允許部分修改。

          五、HTTP 狀態(tài)碼

          服務(wù)器返回的 響應(yīng)報(bào)文 中第一行為狀態(tài)行,包含了狀態(tài)碼以及原因短語,用來告知客戶端請求的結(jié)果。

          狀態(tài)碼類別原因短語1XXInformational(信息性狀態(tài)碼)接收的請求正在處理2XXSuccess(成功狀態(tài)碼)請求正常處理完畢3XXRedirection(重定向狀態(tài)碼)需要進(jìn)行附加操作以完成請求4XXClient Error(客戶端錯(cuò)誤狀態(tài)碼)服務(wù)器無法處理請求5XXServer Error(服務(wù)器錯(cuò)誤狀態(tài)碼)服務(wù)器處理請求出錯(cuò)

          1XX 信息

          100 Continue :表明到目前為止都很正常,客戶端可以繼續(xù)發(fā)送請求或者忽略這個(gè)響應(yīng)。

          2XX 成功

          200 OK

          204 No Content :請求已經(jīng)成功處理,但是返回的響應(yīng)報(bào)文不包含實(shí)體的主體部分。一般在只需要從客戶端往服務(wù)器發(fā)送信息,而不需要返回?cái)?shù)據(jù)時(shí)使用。

          206 Partial Content :表示客戶端進(jìn)行了范圍請求,響應(yīng)報(bào)文包含由 Content-Range 指定范圍的實(shí)體內(nèi)容。

          3XX 重定向

          301 Moved Permanently :永久性重定向

          302 Found :臨時(shí)性重定向

          303 See Other :和 302 有著相同的功能,但是 303 明確要求客戶端應(yīng)該采用 GET 方法獲取資源。

          注:雖然 HTTP 協(xié)議規(guī)定 301、302 狀態(tài)下重定向時(shí)不允許把 POST 方法改成 GET 方法,但是大多數(shù)瀏覽器都會(huì)在 301、302 和 303 狀態(tài)下的重定向把 POST 方法改成 GET 方法。

          304 Not Modified :如果請求報(bào)文首部包含一些條件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不滿足條件,則服務(wù)器會(huì)返回 304 狀態(tài)碼。

          307 Temporary Redirect :臨時(shí)重定向,與 302 的含義類似,但是 307 要求瀏覽器不會(huì)把重定向請求的 POST 方法改成 GET 方法。

          4XX 客戶端錯(cuò)誤

          400 Bad Request :請求報(bào)文中存在語法錯(cuò)誤。

          401 Unauthorized :該狀態(tài)碼表示發(fā)送的請求需要有認(rèn)證信息(BASIC 認(rèn)證、DIGEST 認(rèn)證)。如果之前已進(jìn)行過一次請求,則表示用戶認(rèn)證失敗。

          403 Forbidden :請求被拒絕。

          404 Not Found

          5XX 服務(wù)器錯(cuò)誤

          500 Internal Server Error :服務(wù)器正在執(zhí)行請求時(shí)發(fā)生錯(cuò)誤。

          503 Service Unavailable :服務(wù)器暫時(shí)處于超負(fù)載或正在進(jìn)行停機(jī)維護(hù),現(xiàn)在無法處理請求。

          六、HTTP 首部

          有 4 種類型的首部字段:通用首部字段、請求首部字段、響應(yīng)首部字段和實(shí)體首部字段

          各種首部字段及其含義如下(不需要全記,僅供查閱):

          通用首部字段

          首部字段名說明Cache-Control控制緩存的行為Connection控制不再轉(zhuǎn)發(fā)給代理的首部字段、管理持久連接Date創(chuàng)建報(bào)文的日期時(shí)間Pragma報(bào)文指令Trailer報(bào)文末端的首部一覽Transfer-Encoding指定報(bào)文主體的傳輸編碼方式Upgrade升級(jí)為其他協(xié)議Via代理服務(wù)器的相關(guān)信息Warning錯(cuò)誤通知

          請求首部字段

          首部字段名說明Accept用戶代理可處理的媒體類型Accept-Charset優(yōu)先的字符集Accept-Encoding優(yōu)先的內(nèi)容編碼Accept-Language優(yōu)先的語言(自然語言)AuthorizationWeb 認(rèn)證信息Expect期待服務(wù)器的特定行為From用戶的電子郵箱地址Host請求資源所在服務(wù)器If-Match比較實(shí)體標(biāo)記(ETag)If-Modified-Since比較資源的更新時(shí)間If-None-Match比較實(shí)體標(biāo)記(與 If-Match 相反)If-Range資源未更新時(shí)發(fā)送實(shí)體 Byte 的范圍請求If-Unmodified-Since比較資源的更新時(shí)間(與 If-Modified-Since 相反)Max-Forwards最大傳輸逐跳數(shù)Proxy-Authorization代理服務(wù)器要求客戶端的認(rèn)證信息Range實(shí)體的字節(jié)范圍請求Referer對請求中 URI 的原始獲取方TE傳輸編碼的優(yōu)先級(jí)User-AgentHTTP 客戶端程序的信息

          響應(yīng)首部字段

          首部字段名說明Accept-Ranges是否接受字節(jié)范圍請求Age推算資源創(chuàng)建經(jīng)過時(shí)間ETag資源的匹配信息Location令客戶端重定向至指定 URIProxy-Authenticate代理服務(wù)器對客戶端的認(rèn)證信息Retry-After對再次發(fā)起請求的時(shí)機(jī)要求ServerHTTP 服務(wù)器的安裝信息Vary代理服務(wù)器緩存的管理信息WWW-Authenticate服務(wù)器對客戶端的認(rèn)證信息

          實(shí)體首部字段

          首部字段名說明Allow資源可支持的 HTTP 方法Content-Encoding實(shí)體主體適用的編碼方式Content-Language實(shí)體主體的自然語言Content-Length實(shí)體主體的大小Content-Location替代對應(yīng)資源的 URIContent-MD5實(shí)體主體的報(bào)文摘要Content-Range實(shí)體主體的位置范圍Content-Type實(shí)體主體的媒體類型Expires實(shí)體主體過期的日期時(shí)間Last-Modified資源的最后修改日期時(shí)間

          七、具體應(yīng)用

          連接管理

          1. 短連接與長連接

          當(dāng)瀏覽器訪問一個(gè)包含多張圖片的 HTML 頁面時(shí),除了請求訪問 HTML 頁面資源,還會(huì)請求圖片資源。如果每進(jìn)行一次 HTTP 通信就要新建一個(gè) TCP 連接,那么開銷會(huì)很大。

          長連接只需要建立一次 TCP 連接就能進(jìn)行多次 HTTP 通信。

          從 HTTP/1.1 開始默認(rèn)是長連接的,如果要斷開連接,需要由客戶端或者服務(wù)器端提出斷開,使用 Connection : close;

          在 HTTP/1.1 之前默認(rèn)是短連接的,如果需要使用長連接,則使用 Connection : Keep-Alive。

          那么http如何判斷一個(gè)報(bào)文結(jié)束? 所有http不外乎2情況:

          • 無entity body,則"\r\n\r\n"(兩個(gè)回車符),判斷。
          • 有entity body,則用"Content-Length“字段值判斷。

          參考http消息包的結(jié)束標(biāo)記

          2. 流水線

          默認(rèn)情況下,HTTP 請求是按順序發(fā)出的,下一個(gè)請求只有在當(dāng)前請求收到響應(yīng)之后才會(huì)被發(fā)出。由于會(huì)受到網(wǎng)絡(luò)延遲和帶寬的限制,在下一個(gè)請求被發(fā)送到服務(wù)器之前,可能需要等待很長時(shí)間。

          流水線是在同一條長連接上發(fā)出連續(xù)的請求,而不用等待響應(yīng)返回,這樣可以避免連接延遲。

          Cookie

          HTTP 協(xié)議是無狀態(tài)的,主要是為了讓 HTTP 協(xié)議盡可能簡單,使得它能夠處理大量事務(wù)。HTTP/1.1 引入 Cookie 來保存狀態(tài)信息。

          Cookie 是服務(wù)器發(fā)送到用戶瀏覽器并保存在本地的一小塊數(shù)據(jù),它會(huì)在瀏覽器之后向同一服務(wù)器再次發(fā)起請求時(shí)被攜帶上,用于告知服務(wù)端兩個(gè)請求是否來自同一瀏覽器。由于之后每次請求都會(huì)需要攜帶 Cookie 數(shù)據(jù),因此會(huì)帶來額外的性能開銷(尤其是在移動(dòng)環(huán)境下)。

          Cookie 曾一度用于客戶端數(shù)據(jù)的存儲(chǔ),因?yàn)楫?dāng)時(shí)并沒有其它合適的存儲(chǔ)辦法而作為唯一的存儲(chǔ)手段,但現(xiàn)在隨著現(xiàn)代瀏覽器開始支持各種各樣的存儲(chǔ)方式,Cookie 漸漸被淘汰。新的瀏覽器 API 已經(jīng)允許開發(fā)者直接將數(shù)據(jù)存儲(chǔ)到本地,如使用 Web storage API(本地存儲(chǔ)和會(huì)話存儲(chǔ))或 IndexedDB。

          1. 用途

          會(huì)話狀態(tài)管理(如用戶登錄狀態(tài)、購物車、游戲分?jǐn)?shù)或其它需要記錄的信息)

          個(gè)性化設(shè)置(如用戶自定義設(shè)置、主題等)

          瀏覽器行為跟蹤(如跟蹤分析用戶行為等)

          2. 創(chuàng)建過程

          服務(wù)器發(fā)送的響應(yīng)報(bào)文包含 Set-Cookie 首部字段,客戶端得到響應(yīng)報(bào)文后把 Cookie 內(nèi)容保存到瀏覽器中。

          HTTP/1.0 200 OKContent-type: text/htmlSet-Cookie: yummy_cookie=chocoSet-Cookie: tasty_cookie=strawberry[page content]

          客戶端之后對同一個(gè)服務(wù)器發(fā)送請求時(shí),會(huì)從瀏覽器中取出 Cookie 信息并通過 Cookie 請求首部字段發(fā)送給服務(wù)器。

          GET /sample_page.html HTTP/1.1Host: www.example.orgCookie: yummy_cookie=choco; tasty_cookie=strawberry

          3. 分類

          會(huì)話期 Cookie:瀏覽器關(guān)閉之后它會(huì)被自動(dòng)刪除,也就是說它僅在會(huì)話期內(nèi)有效。

          持久性 Cookie:指定一個(gè)特定的過期時(shí)間(Expires)或有效期(max-age)之后就成為了持久性的 Cookie。

          Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

          4. 作用域

          Domain 標(biāo)識(shí)指定了哪些主機(jī)可以接受 Cookie。如果不指定,默認(rèn)為當(dāng)前文檔的主機(jī)(不包含子域名)。如果指定了 Domain,則一般包含子域名。例如,如果設(shè)置 Domain=mozilla.org,則 Cookie 也包含在子域名中(如 developer.mozilla.org)。

          Path 標(biāo)識(shí)指定了主機(jī)下的哪些路徑可以接受 Cookie(該 URL 路徑必須存在于請求 URL 中)。以字符 %x2F ("/") 作為路徑分隔符,子路徑也會(huì)被匹配。例如,設(shè)置 Path=/docs,則以下地址都會(huì)匹配:

          /docs

          /docs/Web/

          /docs/Web/HTTP

          5. JavaScript

          通過 document.cookie 屬性可創(chuàng)建新的 Cookie,也可通過該屬性訪問非 HttpOnly 標(biāo)記的 Cookie。

          document.cookie="yummy_cookie=choco";document.cookie="tasty_cookie=strawberry";console.log(document.cookie);

          6. HttpOnly

          標(biāo)記為 HttpOnly 的 Cookie 不能被 JavaScript 腳本調(diào)用。跨站腳本攻擊 (XSS) 常常使用 JavaScript 的 document.cookie API 竊取用戶的 Cookie 信息,因此使用 HttpOnly 標(biāo)記可以在一定程度上避免 XSS 攻擊。

          Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

          7. Secure

          標(biāo)記為 Secure 的 Cookie 只能通過被 HTTPS 協(xié)議加密過的請求發(fā)送給服務(wù)端。但即便設(shè)置了 Secure 標(biāo)記,敏感信息也不應(yīng)該通過 Cookie 傳輸,因?yàn)?Cookie 有其固有的不安全性,Secure 標(biāo)記也無法提供確實(shí)的安全保障。

          8. Session

          除了可以將用戶信息通過 Cookie 存儲(chǔ)在用戶瀏覽器中,也可以利用 Session 存儲(chǔ)在服務(wù)器端,存儲(chǔ)在服務(wù)器端的信息更加安全。

          Session 可以存儲(chǔ)在服務(wù)器上的文件、數(shù)據(jù)庫或者內(nèi)存中。也可以將 Session 存儲(chǔ)在 Redis 這種內(nèi)存型數(shù)據(jù)庫中,效率會(huì)更高。

          使用 Session 維護(hù)用戶登錄狀態(tài)的過程如下:

          用戶進(jìn)行登錄時(shí),用戶提交包含用戶名和密碼的表單,放入 HTTP 請求報(bào)文中;

          服務(wù)器驗(yàn)證該用戶名和密碼,如果正確則把用戶信息存儲(chǔ)到 Redis 中,它在 Redis 中的 Key 稱為 Session ID;

          服務(wù)器返回的響應(yīng)報(bào)文的 Set-Cookie 首部字段包含了這個(gè) Session ID,客戶端收到響應(yīng)報(bào)文之后將該 Cookie 值存入瀏覽器中;

          客戶端之后對同一個(gè)服務(wù)器進(jìn)行請求時(shí)會(huì)包含該 Cookie 值,服務(wù)器收到之后提取出 Session ID,從 Redis 中取出用戶信息,繼續(xù)之前的業(yè)務(wù)操作。

          應(yīng)該注意 Session ID 的安全性問題,不能讓它被惡意攻擊者輕易獲取,那么就不能產(chǎn)生一個(gè)容易被猜到的 Session ID 值。此外,還需要經(jīng)常重新生成 Session ID。在對安全性要求極高的場景下,例如轉(zhuǎn)賬等操作,除了使用 Session 管理用戶狀態(tài)之外,還需要對用戶進(jìn)行重新驗(yàn)證,比如重新輸入密碼,或者使用短信驗(yàn)證碼等方式。

          9. 瀏覽器禁用 Cookie

          此時(shí)無法使用 Cookie 來保存用戶信息,只能使用 Session。除此之外,不能再將 Session ID 存放到 Cookie 中,而是使用 URL 重寫技術(shù),將 Session ID 作為 URL 的參數(shù)進(jìn)行傳遞。

          10. Cookie 與 Session 選擇

          Cookie 只能存儲(chǔ) ASCII 碼字符串,而 Session 則可以存取任何類型的數(shù)據(jù),因此在考慮數(shù)據(jù)復(fù)雜性時(shí)首選 Session;

          Cookie 存儲(chǔ)在瀏覽器中,容易被惡意查看。如果非要將一些隱私數(shù)據(jù)存在 Cookie 中,可以將 Cookie 值進(jìn)行加密,然后在服務(wù)器進(jìn)行解密;

          對于大型網(wǎng)站,如果用戶所有的信息都存儲(chǔ)在 Session 中,那么開銷是非常大的,因此不建議將所有的用戶信息都存儲(chǔ)到 Session 中。

          緩存

          1. 優(yōu)點(diǎn)

          緩解服務(wù)器壓力;

          降低客戶端獲取資源的延遲:緩存通常位于內(nèi)存中,讀取緩存的速度更快。并且緩存在地理位置上也有可能比源服務(wù)器來得近,例如瀏覽器緩存。

          2. 實(shí)現(xiàn)方法

          讓代理服務(wù)器進(jìn)行緩存;

          讓客戶端瀏覽器進(jìn)行緩存。

          3. Cache-Control

          HTTP/1.1 通過 Cache-Control 首部字段來控制緩存。

          3.1 禁止進(jìn)行緩存

          no-store 指令規(guī)定不能對請求或響應(yīng)的任何一部分進(jìn)行緩存。

          Cache-Control: no-store

          3.2 強(qiáng)制確認(rèn)緩存

          no-cache 指令規(guī)定緩存服務(wù)器需要先向源服務(wù)器驗(yàn)證緩存資源的有效性,只有當(dāng)緩存資源有效才將能使用該緩存對客戶端的請求進(jìn)行響應(yīng)。

          Cache-Control: no-cache

          3.3 私有緩存和公共緩存

          private 指令規(guī)定了將資源作為私有緩存,只能被單獨(dú)用戶所使用,一般存儲(chǔ)在用戶瀏覽器中。

          Cache-Control: private

          public 指令規(guī)定了將資源作為公共緩存,可以被多個(gè)用戶所使用,一般存儲(chǔ)在代理服務(wù)器中。

          Cache-Control: public

          3.4 緩存過期機(jī)制

          max-age 指令出現(xiàn)在請求報(bào)文中,并且緩存資源的緩存時(shí)間小于該指令指定的時(shí)間,那么就能接受該緩存。

          max-age 指令出現(xiàn)在響應(yīng)報(bào)文中,表示緩存資源在緩存服務(wù)器中保存的時(shí)間。

          Cache-Control: max-age=31536000

          Expires 首部字段也可以用于告知緩存服務(wù)器該資源什么時(shí)候會(huì)過期。

          Expires: Wed, 04 Jul 2012 08:26:05 GMT

          在 HTTP/1.1 中,會(huì)優(yōu)先處理 max-age 指令;

          在 HTTP/1.0 中,max-age 指令會(huì)被忽略掉。

          4. 緩存驗(yàn)證

          需要先了解 ETag 首部字段的含義,它是資源的唯一標(biāo)識(shí)。URL 不能唯一表示資源,例如 http://www.google.com/ 有中文和英文兩個(gè)資源,只有 ETag 才能對這兩個(gè)資源進(jìn)行唯一標(biāo)識(shí)。

          ETag: "82e22293907ce725faf67773957acd12"

          可以將緩存資源的 ETag 值放入 If-None-Match 首部,服務(wù)器收到該請求后,判斷緩存資源的 ETag 值和資源的最新 ETag 值是否一致,如果一致則表示緩存資源有效,返回 304 Not Modified。

          If-None-Match: "82e22293907ce725faf67773957acd12"

          Last-Modified 首部字段也可以用于緩存驗(yàn)證,它包含在源服務(wù)器發(fā)送的響應(yīng)報(bào)文中,指示源服務(wù)器對資源的最后修改時(shí)間。但是它是一種弱校驗(yàn)器,因?yàn)橹荒芫_到一秒,所以它通常作為 ETag 的備用方案。如果響應(yīng)首部字段里含有這個(gè)信息,客戶端可以在后續(xù)的請求中帶上 If-Modified-Since 來驗(yàn)證緩存。服務(wù)器只在所請求的資源在給定的日期時(shí)間之后對內(nèi)容進(jìn)行過修改的情況下才會(huì)將資源返回,狀態(tài)碼為 200 OK。如果請求的資源從那時(shí)起未經(jīng)修改,那么返回一個(gè)不帶有消息主體的 304 Not Modified 響應(yīng)。

          Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
          If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT

          內(nèi)容協(xié)商

          通過內(nèi)容協(xié)商返回最合適的內(nèi)容,例如根據(jù)瀏覽器的默認(rèn)語言選擇返回中文界面還是英文界面。

          1. 類型

          1.1 服務(wù)端驅(qū)動(dòng)型

          客戶端設(shè)置特定的 HTTP 首部字段,例如 Accept、Accept-Charset、Accept-Encoding、Accept-Language,服務(wù)器根據(jù)這些字段返回特定的資源。

          它存在以下問題:

          服務(wù)器很難知道客戶端瀏覽器的全部信息;

          客戶端提供的信息相當(dāng)冗長(HTTP/2 協(xié)議的首部壓縮機(jī)制緩解了這個(gè)問題),并且存在隱私風(fēng)險(xiǎn)(HTTP 指紋識(shí)別技術(shù));

          給定的資源需要返回不同的展現(xiàn)形式,共享緩存的效率會(huì)降低,而服務(wù)器端的實(shí)現(xiàn)會(huì)越來越復(fù)雜。

          1.2 代理驅(qū)動(dòng)型

          服務(wù)器返回 300 Multiple Choices 或者 406 Not Acceptable,客戶端從中選出最合適的那個(gè)資源。

          2. Vary

          Vary: Accept-Language

          在使用內(nèi)容協(xié)商的情況下,只有當(dāng)緩存服務(wù)器中的緩存滿足內(nèi)容協(xié)商條件時(shí),才能使用該緩存,否則應(yīng)該向源服務(wù)器請求該資源。

          例如,一個(gè)客戶端發(fā)送了一個(gè)包含 Accept-Language 首部字段的請求之后,源服務(wù)器返回的響應(yīng)包含 Vary: Accept-Language 內(nèi)容,緩存服務(wù)器對這個(gè)響應(yīng)進(jìn)行緩存之后,在客戶端下一次訪問同一個(gè) URL 資源,并且 Accept-Language 與緩存中的對應(yīng)的值相同時(shí)才會(huì)返回該緩存。

          內(nèi)容編碼

          內(nèi)容編碼將實(shí)體主體進(jìn)行壓縮,從而減少傳輸?shù)臄?shù)據(jù)量。

          常用的內(nèi)容編碼有:gzip、compress、deflate、identity。

          瀏覽器發(fā)送 Accept-Encoding 首部,其中包含有它所支持的壓縮算法,以及各自的優(yōu)先級(jí)。服務(wù)器則從中選擇一種,使用該算法對響應(yīng)的消息主體進(jìn)行壓縮,并且發(fā)送 Content-Encoding 首部來告知瀏覽器它選擇了哪一種算法。由于該內(nèi)容協(xié)商過程是基于編碼類型來選擇資源的展現(xiàn)形式的,在響應(yīng)的 Vary 首部至少要包含 Content-Encoding。

          范圍請求

          如果網(wǎng)絡(luò)出現(xiàn)中斷,服務(wù)器只發(fā)送了一部分?jǐn)?shù)據(jù),范圍請求可以使得客戶端只請求服務(wù)器未發(fā)送的那部分?jǐn)?shù)據(jù),從而避免服務(wù)器重新發(fā)送所有數(shù)據(jù)。

          1. Range

          在請求報(bào)文中添加 Range 首部字段指定請求的范圍。

          GET /z4d4kWk.jpg HTTP/1.1Host: i.imgur.comRange: bytes=0-1023

          請求成功的話服務(wù)器返回的響應(yīng)包含 206 Partial Content 狀態(tài)碼。

          HTTP/1.1 206 Partial ContentContent-Range: bytes 0-1023/146515Content-Length: 1024...(binary content)

          2. Accept-Ranges

          響應(yīng)首部字段 Accept-Ranges 用于告知客戶端是否能處理范圍請求,可以處理使用 bytes,否則使用 none。

          Accept-Ranges: bytes

          3. 響應(yīng)狀態(tài)碼

          在請求成功的情況下,服務(wù)器會(huì)返回 206 Partial Content 狀態(tài)碼。

          在請求的范圍越界的情況下,服務(wù)器會(huì)返回 416 Requested Range Not Satisfiable 狀態(tài)碼。

          在不支持范圍請求的情況下,服務(wù)器會(huì)返回 200 OK 狀態(tài)碼。

          分塊傳輸編碼

          Chunked Transfer Coding,可以把數(shù)據(jù)分割成多塊,讓瀏覽器逐步顯示頁面。

          多部分對象集合

          一份報(bào)文主體內(nèi)可含有多種類型的實(shí)體同時(shí)發(fā)送,每個(gè)部分之間用 boundary 字段定義的分隔符進(jìn)行分隔,每個(gè)部分都可以有首部字段。

          例如,上傳多個(gè)表單時(shí)可以使用如下方式:

          Content-Type: multipart/form-data; boundary=AaB03x--AaB03xContent-Disposition: form-data; name="submit-name"Larry--AaB03xContent-Disposition: form-data; name="files"; filename="file1.txt"Content-Type: text/plain... contents of file1.txt ...--AaB03x--

          虛擬主機(jī)

          HTTP/1.1 使用虛擬主機(jī)技術(shù),使得一臺(tái)服務(wù)器擁有多個(gè)域名,并且在邏輯上可以看成多個(gè)服務(wù)器。

          通信數(shù)據(jù)轉(zhuǎn)發(fā)

          1. 代理

          代理服務(wù)器接受客戶端的請求,并且轉(zhuǎn)發(fā)給其它服務(wù)器。

          使用代理的主要目的是:

          緩存

          負(fù)載均衡

          網(wǎng)絡(luò)訪問控制

          訪問日志記錄

          代理服務(wù)器分為正向代理和反向代理兩種:

          用戶察覺得到正向代理的存在。

          而反向代理一般位于內(nèi)部網(wǎng)絡(luò)中,用戶察覺不到。

          2. 網(wǎng)關(guān)

          與代理服務(wù)器不同的是,網(wǎng)關(guān)服務(wù)器會(huì)將 HTTP 轉(zhuǎn)化為其它協(xié)議進(jìn)行通信,從而請求其它非 HTTP 服務(wù)器的服務(wù)。

          3. 隧道

          使用 SSL 等加密手段,在客戶端和服務(wù)器之間建立一條安全的通信線路。

          八、HTTPs

          HTTP 有以下安全性問題:

          使用明文進(jìn)行通信,內(nèi)容可能會(huì)被竊聽;

          不驗(yàn)證通信方的身份,通信方的身份有可能遭遇偽裝;

          無法證明報(bào)文的完整性,報(bào)文有可能遭篡改。

          HTTPs 并不是新協(xié)議,而是讓 HTTP 先和 SSL(Secure Sockets Layer)通信,再由 SSL 和 TCP 通信,也就是說 HTTPs 使用了隧道進(jìn)行通信。

          通過使用 SSL,HTTPs 具有了加密(防竊聽)、認(rèn)證(防偽裝)和完整性保護(hù)(防篡改)。

          加密

          1. 對稱密鑰加密

          對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

          優(yōu)點(diǎn):運(yùn)算速度快;

          缺點(diǎn):無法安全地將密鑰傳輸給通信方。

          2.非對稱密鑰加密

          非對稱密鑰加密,又稱公開密鑰加密(Public-Key Encryption),加密和解密使用不同的密鑰。

          公開密鑰所有人都可以獲得,通信發(fā)送方獲得接收方的公開密鑰之后,就可以使用公開密鑰進(jìn)行加密,接收方收到通信內(nèi)容后使用私有密鑰解密。

          非對稱密鑰除了用來加密,還可以用來進(jìn)行簽名。因?yàn)樗接忻荑€無法被其他人獲取,因此通信發(fā)送方使用其私有密鑰進(jìn)行簽名,通信接收方使用發(fā)送方的公開密鑰對簽名進(jìn)行解密,就能判斷這個(gè)簽名是否正確。

          優(yōu)點(diǎn):可以更安全地將公開密鑰傳輸給通信發(fā)送方;

          缺點(diǎn):運(yùn)算速度慢。

          3. HTTPs 采用的加密方式

          HTTPs 采用混合的加密機(jī)制,使用非對稱密鑰加密用于傳輸對稱密鑰來保證傳輸過程的安全性,之后使用對稱密鑰加密進(jìn)行通信來保證通信過程的效率。(下圖中的 Session Key 就是對稱密鑰)

          認(rèn)證

          通過使用 證書 來對通信方進(jìn)行認(rèn)證。

          數(shù)字證書認(rèn)證機(jī)構(gòu)(CA,Certificate Authority)是客戶端與服務(wù)器雙方都可信賴的第三方機(jī)構(gòu)。

          服務(wù)器的運(yùn)營人員向 CA 提出公開密鑰的申請,CA 在判明提出申請者的身份之后,會(huì)對已申請的公開密鑰做數(shù)字簽名,然后分配這個(gè)已簽名的公開密鑰,并將該公開密鑰放入公開密鑰證書后綁定在一起。

          進(jìn)行 HTTPs 通信時(shí),服務(wù)器會(huì)把證書發(fā)送給客戶端??蛻舳巳〉闷渲械墓_密鑰之后,先使用數(shù)字簽名進(jìn)行驗(yàn)證,如果驗(yàn)證通過,就可以開始通信了。

          通信開始時(shí),客戶端需要使用服務(wù)器的公開密鑰將自己的私有密鑰傳輸給服務(wù)器,之后再進(jìn)行對稱密鑰加密。

          完整性保護(hù)

          SSL 提供報(bào)文摘要功能來進(jìn)行完整性保護(hù)。

          HTTP 也提供了 MD5 報(bào)文摘要功能,但不是安全的。例如報(bào)文內(nèi)容被篡改之后,同時(shí)重新計(jì)算 MD5 的值,通信接收方是無法意識(shí)到發(fā)生了篡改。

          HTTPs 的報(bào)文摘要功能之所以安全,是因?yàn)樗Y(jié)合了加密和認(rèn)證這兩個(gè)操作。試想一下,加密之后的報(bào)文,遭到篡改之后,也很難重新計(jì)算報(bào)文摘要,因?yàn)闊o法輕易獲取明文。

          HTTPs 的缺點(diǎn)

          因?yàn)樾枰M(jìn)行加密解密等過程,因此速度會(huì)更慢;

          需要支付證書授權(quán)的高額費(fèi)用。

          九、HTTP/2.0

          HTTP/1.x 缺陷

          HTTP/1.x 實(shí)現(xiàn)簡單是以犧牲性能為代價(jià)的:

          客戶端需要使用多個(gè)連接才能實(shí)現(xiàn)并發(fā)和縮短延遲;

          不會(huì)壓縮請求和響應(yīng)首部,從而導(dǎo)致不必要的網(wǎng)絡(luò)流量;

          不支持有效的資源優(yōu)先級(jí),致使底層 TCP 連接的利用率低下。

          二進(jìn)制分幀層

          HTTP/2.0 將報(bào)文分成 HEADERS 幀和 DATA 幀,它們都是二進(jìn)制格式的。

          在通信過程中,只會(huì)有一個(gè) TCP 連接存在,它承載了任意數(shù)量的雙向數(shù)據(jù)流(Stream)。

          一個(gè)數(shù)據(jù)流(Stream)都有一個(gè)唯一標(biāo)識(shí)符和可選的優(yōu)先級(jí)信息,用于承載雙向信息。

          消息(Message)是與邏輯請求或響應(yīng)對應(yīng)的完整的一系列幀。

          幀(Frame)是最小的通信單位,來自不同數(shù)據(jù)流的幀可以交錯(cuò)發(fā)送,然后再根據(jù)每個(gè)幀頭的數(shù)據(jù)流標(biāo)識(shí)符重新組裝。

          服務(wù)端推送

          HTTP/2.0 在客戶端請求一個(gè)資源時(shí),會(huì)把相關(guān)的資源一起發(fā)送給客戶端,客戶端就不需要再次發(fā)起請求了。例如客戶端請求 page.html 頁面,服務(wù)端就把 script.js 和 style.css 等與之相關(guān)的資源一起發(fā)給客戶端。

          首部壓縮

          HTTP/1.1 的首部帶有大量信息,而且每次都要重復(fù)發(fā)送。

          HTTP/2.0 要求客戶端和服務(wù)器同時(shí)維護(hù)和更新一個(gè)包含之前見過的首部字段表,從而避免了重復(fù)傳輸。

          不僅如此,HTTP/2.0 也使用 Huffman 編碼對首部字段進(jìn)行壓縮。

          十、HTTP/1.1 新特性

          詳細(xì)內(nèi)容請見上文

          默認(rèn)是長連接

          支持流水線

          支持同時(shí)打開多個(gè) TCP 連接

          支持虛擬主機(jī)

          新增狀態(tài)碼 100

          支持分塊傳輸編碼

          新增緩存處理指令 max-age

          十一、GET 和 POST 比較

          數(shù)據(jù)傳輸方式

          GET提交的數(shù)據(jù)會(huì)放在URL之后,以?分割URL和傳輸數(shù)據(jù),參數(shù)之間以&相連,如EditPosts.aspx?name=test1&id=123456。 POST方法是把提交的數(shù)據(jù)放在HTTP包的Body中。(一個(gè)形象地比喻是:當(dāng)執(zhí)行GET請求的時(shí)候,要給汽車貼上GET的標(biāo)簽(設(shè)置method為GET),而且要求把傳送的數(shù)據(jù)放在車頂上(url中)以方便記錄。如果是POST請求,就要在車上貼上POST的標(biāo)簽,并把貨物放在車廂里。)

          因?yàn)?URL 只支持 ASCII 碼,因此 GET 的參數(shù)中如果存在中文等字符就需要先進(jìn)行編碼。例如 中文 會(huì)轉(zhuǎn)換為 %E4%B8%AD%E6%96%87,而空格會(huì)轉(zhuǎn)換為 %20。POST 參考支持標(biāo)準(zhǔn)字符集。

          保密性

          GET方式提交數(shù)據(jù),會(huì)帶來安全問題,比如一個(gè)登錄頁面,通過GET方式提交數(shù)據(jù)時(shí),用戶名和密碼將出現(xiàn)在URL上,如果頁面可以被緩存或者其他人可以訪問這臺(tái)機(jī)器,就可以從歷史記錄獲得該用戶的賬號(hào)和密碼

          但是,不能因?yàn)?POST 參數(shù)存儲(chǔ)在實(shí)體主體中就認(rèn)為它的安全性更高,因?yàn)檎諛涌梢酝ㄟ^一些抓包工具(Fiddler)查看。

          冪等性

          冪等的 HTTP 方法,同樣的請求被執(zhí)行一次與連續(xù)執(zhí)行多次的效果是一樣的,服務(wù)器的狀態(tài)也是一樣的。換句話說就是,冪等方法不應(yīng)該具有副作用(統(tǒng)計(jì)用途除外)。

          所有的安全方法也都是冪等的。

          在正確實(shí)現(xiàn)的條件下,GET,HEAD,PUT 和 DELETE 等方法都是冪等的,而 POST 方法不是。

          傳輸數(shù)據(jù)的大小

          首先聲明:HTTP協(xié)議沒有對傳輸?shù)臄?shù)據(jù)大小進(jìn)行限制,HTTP協(xié)議規(guī)范也沒有對URL長度進(jìn)行限制。

          而在實(shí)際開發(fā)中存在的限制主要有:

          **GET:**特定瀏覽器和服務(wù)器對URL長度有限制,例如 IE對URL長度的限制是2083字節(jié)(2K+35)。對于其他瀏覽器,如Netscape、FireFox等,理論上沒有長度限制,其限制取決于操作系 統(tǒng)的支持。

          因此對于GET提交時(shí),傳輸數(shù)據(jù)就會(huì)受到URL長度的 限制。

          **POST:**由于不是通過URL傳值,理論上數(shù)據(jù)不受 限。但實(shí)際各個(gè)WEB服務(wù)器會(huì)規(guī)定對post提交數(shù)據(jù)大小進(jìn)行限制,Apache、IIS6都有各自的配置。

          安全

          安全的 HTTP 方法不會(huì)改變服務(wù)器狀態(tài),也就是說它只是可讀的。

          GET 方法是安全的,而 POST 卻不是,因?yàn)?POST 的目的是傳送實(shí)體主體內(nèi)容,這個(gè)內(nèi)容可能是用戶上傳的表單數(shù)據(jù),上傳成功之后,服務(wù)器可能把這個(gè)數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫中,因此狀態(tài)也就發(fā)生了改變。

          安全的方法除了 GET 之外還有:HEAD、OPTIONS。

          不安全的方法除了 POST 之外還有 PUT、DELETE。

          速度

          GET產(chǎn)生一個(gè)TCP數(shù)據(jù)包;POST產(chǎn)生兩個(gè)TCP數(shù)據(jù)包。

          對于GET方式的請求,瀏覽器會(huì)把http header和data一并發(fā)送出去,服務(wù)器響應(yīng)200(返回?cái)?shù)據(jù));而對于POST,瀏覽器先發(fā)送header,服務(wù)器響應(yīng)100 continue,瀏覽器再發(fā)送data,服務(wù)器響應(yīng)200 ok(返回?cái)?shù)據(jù))。

          參考

          關(guān)于HTTP協(xié)議,一篇就夠了HTTPGET和POST兩種基本請求方法的區(qū)別

          本文來源:http://8rr.co/zgQS

          最后

          剛整理 2020 年全套最新精品技術(shù)資料免費(fèi)發(fā)給你! (原價(jià)最少8999元,超2000G!)



          領(lǐng)取 看看下面!!

          1、點(diǎn)贊 + 評(píng)論 (勾選 “轉(zhuǎn)發(fā)” )

          2、關(guān)注小編私信。點(diǎn)擊頭像,關(guān)注。并私信回復(fù)關(guān)鍵詞: 1024


          主站蜘蛛池模板: 国模吧无码一区二区三区| 国产精品一区二区久久| 麻豆精品久久久一区二区| 久久精品一区二区三区中文字幕| 波多野结衣电影区一区二区三区 | 蜜桃无码一区二区三区| 性色A码一区二区三区天美传媒| 国产91精品一区二区麻豆网站| 国产伦精品一区二区三区不卡| 又紧又大又爽精品一区二区| 成人精品一区二区三区不卡免费看| 亚洲制服中文字幕第一区| 国产SUV精品一区二区四| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 精品国产aⅴ无码一区二区| 亚洲熟女乱色一区二区三区| 一区二区三区视频免费| 亚洲av无码不卡一区二区三区 | 日本免费一区尤物| 中文字幕精品无码一区二区| 亚洲香蕉久久一区二区| 蜜桃视频一区二区| 精品无码人妻一区二区三区| 免费无码一区二区| 91午夜精品亚洲一区二区三区| 日韩精品无码久久一区二区三| 无码人妻精品一区二区三区东京热 | 人妻少妇久久中文字幕一区二区| 精品国产免费观看一区| 精品一区二区三区中文字幕| 日本人的色道www免费一区| 日本免费一区二区三区四区五六区| 中文字幕无码不卡一区二区三区| 国产在线观看一区精品| 国产福利日本一区二区三区| 亚洲AV综合色区无码一区爱AV| 国产精品一区二区电影| 国产经典一区二区三区蜜芽| 精品aⅴ一区二区三区| 国产成人一区二区在线不卡 | 中文字幕AV无码一区二区三区|