- HTTP/2 in Action 中文版
- (美)Barry Pollard(巴里·波拉德)
- 7108字
- 2020-08-06 15:52:05
1.3 HTTP的語法和歷史
1989年,在CERN,Tim Berners-Lee和他的團隊啟動了對HTTP的研究。該研究旨在實現(xiàn)一種計算機互聯(lián)網(wǎng)絡,并通過此網(wǎng)絡提供對研究成果的訪問,且將研究鏈接起來,以便它們可以方便即時地相互引用——單擊一個鏈接就可以打開相關的文檔。此類系統(tǒng)的構(gòu)想已經(jīng)存在相當長一段時間,超文本一詞也于20世紀60年代問世。隨著20世紀80年代因特網(wǎng)的發(fā)展,實現(xiàn)此構(gòu)想成為可能。在1989年和1990年間,Berners-Lee發(fā)布了構(gòu)建此類系統(tǒng)的提議[6]。緊接著他構(gòu)建了第一個基于HTTP的Web服務器,以及第一個Web瀏覽器,用以請求并顯示HTML文檔。
1.3.1 HTTP/0.9
HTTP的第一個規(guī)范是1991年發(fā)布的0.9版本。此規(guī)范文檔[7]只有不到700個單詞。該規(guī)范指定,通過TCP/IP(或類似的面向連接的服務)與服務器和端口(可選的,如果未指定端口,則使用80)建立連接。客戶端應發(fā)送一行ASCII文本,包括GET、文檔地址(無空格)、回車符和換行符(回車是可選的)。服務器使用HTML格式的消息進行響應,該消息被定義為“ASCII字符的字節(jié)流”。規(guī)范還指定,“通過服務器關閉連接來終止消息”,這就是為什么在前面的示例中,在每個請求之后都關閉了連接。在處理錯誤時,規(guī)范聲明:“錯誤響應以可讀的文本顯示,使用HTML語法。除了文本的內(nèi)容,沒有辦法區(qū)分錯誤響應和正確響應。”在文檔結(jié)尾處,規(guī)范指出:“請求是冪等的。服務器不需要在斷開連接后存儲關于請求的任何信息。”本規(guī)范為我們提供了HTTP的無狀態(tài)特性,這是一把雙刃劍,有利(這很簡單)也有弊(因為必須附加HTTP cookies等技術以允許狀態(tài)跟蹤,這對于復雜的應用程序是必需的)。
如下是HTTP/0.9可能僅有的指令:

當然,請求的資源(/section/page.html)可以改變,但是句法中的其他部分是不變的。
當時,還沒有HTTP頭字段(這里稱為HTTP首部)或任何其他媒體(如圖像)的概念。令人驚訝的是,從這個旨在為研究機構(gòu)提供對信息的便捷訪問的、簡單的請求/響應協(xié)議,很快催生了當今世界不可或缺又豐富多彩的萬維網(wǎng)。即便在早期,Berners-Lee也稱他的發(fā)明為WorldWideWeb(沒有空格),這體現(xiàn)了他對于此項目的遠見,以及想讓其成為一個全球系統(tǒng)的目標。
1.3.2 HTTP/1.0
萬維網(wǎng)如一顆新星,迅速崛起。NetCraft[8]數(shù)據(jù)顯示,到1995年9月,網(wǎng)絡上有19705個主機名。一個月后,這個數(shù)字躍升至31568,此后也一直以驚人的速度增長。在筆者寫作本書時,世界上已經(jīng)有接近20億個網(wǎng)站。到1995年,HTTP/0.9這個簡單協(xié)議的局限性已經(jīng)不可忽視,大多數(shù)Web服務器都已經(jīng)實現(xiàn)了遠超0.9規(guī)范的擴展。由Dave Raggett領導的HTTP工作組(HTTP WG)開始研究HTTP/1.0,試圖記錄“協(xié)議的共同用法”。該文檔就是RFC 1945[9],其于1996年5月發(fā)布。RFC(征求意見稿)文件由IETF發(fā)布。它可以作為正式標準被接受,也可以作為非正式文件用于存檔。HTTP/1.0 RFC[10]屬于后者,它并不是正式規(guī)范。在文檔的開頭部分,它聲稱自己是一個“備忘錄”,并申明:“本備忘錄為互聯(lián)網(wǎng)社區(qū)提供信息。本備忘錄不規(guī)定任何形式的互聯(lián)網(wǎng)標準。”
盡管不是正式標準,HTTP/1.0還是新增了一些關鍵特性,包含:
? 更多的請求方法。除了先前定義的GET方法,新增了HEAD和POST方法。
? 為所有的消息添加HTTP版本號字段。此字段是可選的,為了向后兼容,默認情況下使用HTTP/0.9。
? HTTP首部。它可以與請求和響應一起發(fā)送,以提供與正在執(zhí)行的請求或發(fā)送的響應相關的更多信息。
? 一個三位整數(shù)的響應狀態(tài)碼,(例如)用來表示響應是否成功。此狀態(tài)碼還可以用來表示重定向請求、條件請求和錯誤狀態(tài)(404 - Not Found是其中最著名的錯誤狀態(tài)之一)。
在使用協(xié)議的過程中,一些急需的擴展應運而生。并且HTTP/1.0旨在記錄現(xiàn)實世界中多數(shù)Web服務器上已經(jīng)發(fā)生的事情,而不是定義新的功能。特性的擴增給Web帶來了大量的新機會。其中,通過使用HTTP響應首部來定義正文中的內(nèi)容類型,人們終于可以向網(wǎng)頁中添加多媒體內(nèi)容。
HTTP/1.0的方法
GET方法與HTTP/0.9中的基本相同,但是新增的首部允許客戶端發(fā)送條件GET(僅當在客戶端上次請求之后,資源發(fā)生變化時,才請求資源內(nèi)容;否則,告訴客戶端資源沒變化,繼續(xù)使用舊的副本)。此外,我們之前提到過,用戶可以使用GET方法獲取更多的資源,而不僅僅是超文本文檔,比如使用HTTP下載圖像、視頻或其他類型的媒體內(nèi)容。
HEAD方法允許客戶端獲取資源的所有元信息(例如HTTP頭)而無須下載資源本身。在很多場景下,此方法很有用。例如,Google的網(wǎng)絡爬蟲可以檢查資源是否已被更改并僅在其改變時才下載,從而為Google和目標Web服務器節(jié)省資源。
POST方法就更有趣了,它允許客戶端發(fā)送數(shù)據(jù)到Web服務器。如果Web服務器準備好接收數(shù)據(jù)并執(zhí)行相應的操作,那么用戶可以通過HTTP POST一個新的HTML文件到Web服務器上,而不是像標準的文件傳輸方法一樣,將它直接放到服務器上。POST方法不局限于發(fā)送完整的文件,它可以發(fā)送更小的數(shù)據(jù)。網(wǎng)站上的表單通常使用POST方法發(fā)送,將表單的內(nèi)容作為鍵值對放在HTTP請求體中發(fā)送。也就是說,POST方法允許將內(nèi)容作為HTTP請求的一部分從客戶端發(fā)送到服務器,這表示HTTP請求終于和HTTP響應一樣,擁有了正文部分。
實際上,GET方法允許將數(shù)據(jù)包含在URL尾部指定的查詢參數(shù)中發(fā)送,通常放在?字符之后。例如,https://www.google.com/?q=search+string告訴Google你正在搜索關鍵詞search string。查詢參數(shù)在最早的URI(Uniform Resource Identifier,統(tǒng)一資源標識符)規(guī)范[11]中定義,但它們提供了額外的參數(shù)來指明URI,而不是用它們向Web服務器上傳數(shù)據(jù)。URL受到長度和內(nèi)容方面的限制(例如,無法發(fā)送二進制數(shù)據(jù)),并且某些機密數(shù)據(jù)(密碼、信用卡數(shù)據(jù)等)也不應出現(xiàn)在URL中,因為很容易就可以在屏幕和瀏覽器歷史記錄中看到這些數(shù)據(jù)。當URL被分享出去時,這些數(shù)據(jù)也包括在內(nèi)。因此,POST方法通常是一種更好的數(shù)據(jù)發(fā)送方式,其中的數(shù)據(jù)也不是那么顯而易見(盡管在通過透明的HTTP而不是安全的HTTPS發(fā)送時仍應小心,稍后會討論這一點)。另一個區(qū)別是GET請求是冪等的,而POST請求不是。這意味著對于同一個URL的多個GET請求,應始終返回相同的結(jié)果;而對于同一URL請求的多個POST請求,則可能不會返回相同的結(jié)果。例如,我們刷新網(wǎng)站上的標準頁面,它應該顯示相同的內(nèi)容。如果在電子商務網(wǎng)站刷新確認頁面,則瀏覽器可能會詢問你,是否真的要重新提交數(shù)據(jù),這可能會導致你重復下單,盡管在編寫電子商務網(wǎng)站應用程序時,就應該確保不會發(fā)生這種情況!
HTTP請求首部
HTTP/0.9只使用一行指令GET資源,而HTTP/1.0引入了HTTP首部(或者叫首部)。這些首部允許請求向服務器提供附加信息,可以使用首部來決定如何處理請求。HTTP首部在原始請求行之后的單獨行上提供。HTTP GET請求已從:

變成了:

或者(沒有首部的時候)

也就是說,在第一行中添加了一個版本部分(可選的,如果未指定,則默認為HTTP/0.9)。并且可選的HTTP首部之后跟著兩個回車/換行符(以下簡稱為回車符)。第二行必須發(fā)送一個空行,用于表示(可選的)請求首部部分已完成。
HTTP首部使用首部名稱、冒號和首部內(nèi)容表示。根據(jù)規(guī)范,首部名稱(而不是內(nèi)容)不區(qū)分大小寫。當使用空格或制表符開始新的一行時,首部可以跨越多行,但并不推薦這種做法;很少有客戶端或服務器使用此格式,所以它們可能無法正確處理這種格式。可以發(fā)送具有相同名稱的多個首部,在語義上這與發(fā)送以逗號分隔的版本完全相同。也就是說,

和下面這樣的處理完全相同:

HTTP/1.0定義了一些標準首部,而我們這里的示例演示了在HTTP/1.0中如何提供自定義首部(在此示例中為Header1),而且無須更新版本協(xié)議。在設計協(xié)議時就考慮到了擴展性。并且,規(guī)范明確指出,這些字段不能讓接收者認為是可以識別的,或許可以被忽略,然而標準首部應該由符合HTTP/1.0規(guī)范的服務器處理[12]。
一個經(jīng)典的HTTP/1.0 GET請求是:

此請求告訴服務器你可以接受哪些格式的響應(HTML、XHTML和XML等),你可以接受多種編碼格式(例如,gzip、deflate和brotli,這些壓縮算法用于壓縮通過HTTP發(fā)送的數(shù)據(jù)),你傾向于使用哪種語言(英式英語、美國英語,或者任何其他形式的英語),以及你正在使用的瀏覽器(MyAwesomeWebBrowser 1.1)。它還告知服務器保持連接(稍后會講)。整個請求用兩個回車符結(jié)束。從這里開始,出于可讀性考慮,我們?nèi)サ袅藫Q行符。你可以假設請求中的最后一行后跟兩個回車符。
HTTP響應狀態(tài)碼
一個經(jīng)典的來自HTTP/1.0服務器的響應如下:

此處省略的內(nèi)容是HTML的剩余部分。可以看到,響應的第一行包括響應消息的HTTP版本(HTTP/1.0)、三位數(shù)的HTTP狀態(tài)碼(200)以及該狀態(tài)碼的文本描述(OK)。狀態(tài)碼和描述是HTTP/1.0中的新概念。在HTTP/0.9中,沒有響應碼這樣的概念,錯誤只能在返回的HTML本身中給出。表1.1顯示了HTTP/1.0規(guī)范中定義的HTTP響應碼[13]。
表1.1 HTTP/1.0響應碼

聰明的讀者可能會注意到,一些HTTP/1.0 RFC早期草稿中的響應碼(如203、303、402)沒有列出。在最終發(fā)布的RFC中,沒有包含這些狀態(tài)碼。其中有一些狀態(tài)碼在HTTP/1.1中又回歸了,但通常它們具有不同的描述和含義。IANA(Internet Assigned Numbers Authority,互聯(lián)網(wǎng)數(shù)字分配機構(gòu))維護所有HTTP版本的狀態(tài)碼列表。但表1.1中所列狀態(tài)碼(最初在HTTP/1.0中定義)是最常用的。
很顯然,某些狀態(tài)碼的含義有重疊。例如,你可能會疑惑,無法識別的請求,其狀態(tài)碼是400(錯誤請求)還是501(未實現(xiàn))。把響應碼設計為寬泛的形式,這樣每個應用程序都可以選擇最合適的狀態(tài)碼。該規(guī)范還指出,響應碼是可擴展的,因此可以根據(jù)需要添加新代碼而無須更改協(xié)議。這也是響應碼會按首個數(shù)字分類的原因。一個新的響應碼(如504)可能無法被已有的HTTP/1.0客戶端所理解,但客戶端知道請求是由于服務端的某種原因而失敗,并且可以像處理其他5xx響應碼一樣來處理它。
HTTP響應首部
在返回響應的第一行之后,會有一到多行HTTP/1響應首部。請求首部和響應首部遵循同樣的格式。在響應首部之后,是兩個回車符,然后是響應體,如下加粗的部分所示:

隨著HTTP/1.0的發(fā)布,HTTP語法得到了極大的擴展,能夠使用它創(chuàng)建動態(tài)的功能豐富的應用程序,而不僅僅是HTTP/0.9時的簡單文檔獲取程序。HTTP也變得越來越復雜,從大約700個單詞的HTTP/0.9規(guī)范擴展到近20 000個單詞的HTTP/1.0 RFC。即使發(fā)布了HTTP/1.0,HTTP工作組也認為其只是記錄當前使用的權(quán)宜之計,并且已經(jīng)著手HTTP/1.1的工作。我們之前提到過,HTTP/1.0的發(fā)布主要是為了給已經(jīng)在使用的HTTP提供一些標準和文檔,而不是為客戶端和服務器定義新語法。除了新的響應碼外,其他方法(例如PUT、DELETE、LINK和UNLINK)和當時正在使用的列在RFC的附錄中的其他HTTP首部,在HTTP/1.1中變成了標準。HTTP的成功使得工作組在將HTTP推向全球的短短5年之后就難以跟上實際應用的步伐。
1.3.3 HTTP/1.1
如前所述,HTTP的第一個版本0.9版,為獲取基于文本的文檔提供了基本方法。現(xiàn)在其已被擴展到更完善的1.0版,并且在1.1版中被進一步標準化和完善。正如版本號所表示的,HTTP/1.1更像是對HTTP/1.0的調(diào)整,它沒有從根本上改變協(xié)議。從0.9到1.0是一個較大的變化,增加了HTTP首部。HTTP/1.1做了進一步的改進,以便充分利用HTTP協(xié)議(例如,持久連接、強制響應首部、更好的緩存選項和分塊編碼)。更重要的是,它提供了一個正式標準,后來的萬維網(wǎng)正是基于它構(gòu)筑。雖然HTTP的基礎知識很容易理解,但是里面許多錯綜復雜的細節(jié)、實現(xiàn)方式的不同,以及正式標準的缺乏使得它難以擴展。
HTTP/1.1的首個規(guī)范發(fā)布于1997年1月[14](HTTP/1.0規(guī)范發(fā)布之后僅僅過了9個月),于1999年6月[15]被新版本替換,然后于2014年6月第3個版本[16]發(fā)布。每個新版本的發(fā)布都會廢除之前的版本。到如今,HTTP規(guī)范已經(jīng)超過305頁,有將近100 000個單詞。這突顯了它的成長速度。弄清楚HTTP復雜的使用方法至關重要。實際上,在撰寫本書時,HTTP規(guī)范又更新了[17],此規(guī)范很快就會發(fā)布。從根本上說,HTTP/1.1和HTTP/1.0并沒有太大的區(qū)別。但是在HTTP問世之后的20年中,網(wǎng)絡的爆炸式增長,使其增加了許多新的功能,以及文檔顯示的新形式。
描述HTTP/1.1本身就需要一本書,但我們只討論一些要點,為本書進行后面HTTP/2的討論提供背景知識。HTTP/1.1的許多附加功能是通過HTTP首部引入的,HTTP首部本身是在HTTP/1.0中引入的,這意味著HTTP的基本結(jié)構(gòu)在兩個版本之間沒有變化。強制首部和持久連接是HTTP/1.0語法的兩個顯著變化。
強制添加Host首部
HTTP請求行(如GET指令)中的URL不是一個包含絕對路徑的URL(如http://www.example.com/section/page.html),而是一個只包含相對路徑的URL(如/section/page.html)。在設計HTTP協(xié)議之初,一個Web服務器只能托管一個網(wǎng)站(但是這個網(wǎng)站上可以有很多部分和頁面)。所以URL的主機名部分是不言自明的,因為在發(fā)送HTTP請求之前,用戶肯定已經(jīng)連接到了主機。如今,很多Web服務器上面有多個網(wǎng)站(虛擬主機托管),所以告訴服務器要訪問哪個網(wǎng)站和訪問哪個相對URL同樣重要。此功能可以通過下面的方法實現(xiàn):將HTTP請求中的URL修改為完整的包含絕對路徑的URL。但如果采用這種方法,則很多現(xiàn)有的Web服務器和客戶端都不能正常運行。所以,我們在請求首部中添加Host來實現(xiàn)該功能:

這個首部在HTTP/1.0中是可選的,但是在HTTP/1.1中它是必選項。下面的請求從技術上來講格式并不正確,因為它聲明自己使用HTTP/1.1,卻沒有提供一個Host首部:

根據(jù)HTTP/1.1的規(guī)范[18],請求應該被服務器拒絕(使用一個400狀態(tài)碼)。但是多數(shù)Web服務器很寬容,對于此類請求它們會使用一個默認的Host。
將Host作為必選項是HTTP/1.1的重要改進,這使得服務器能夠充分利用虛擬主機托管技術,無須顧及因為新增網(wǎng)站而新加獨立主機所帶來的復雜性,從而使得網(wǎng)絡繁榮發(fā)展。另外,如果沒有這個改進,我們會更早遭遇IPv4的IP地址不足的限制。但從另一個角度來講,如果沒有這個方式來解決此限制,可能會更積極地推動IPv6的發(fā)展。但是在撰寫本書時,IPv6還在推廣的過程中,盡管它已經(jīng)存在20多年了!
指定強制Host首部字段,而不是將相對URL更改為絕對URL,帶來了一些爭論[19]。HTTP/1.1引入的HTTP代理允許通過中間HTTP服務器連接到目標HTTP服務器。代理的語法要求所有的請求使用完整的絕對URL,但實際的Web服務器(也稱為源服務器)要求強制使用Host首部。我們知道,使用Host首部對于避免破壞現(xiàn)有服務器是必要的,但它強制要求HTTP/1.1客戶端和服務器使用虛擬主機式請求,只有這樣才能完全兼容HTTP/1.1實現(xiàn)。有人認為,在HTTP的未來某個版本中,這種情況會得到更好的解決。HTTP/1.1規(guī)范聲明,“為了支持在某些未來版本的HTTP中,轉(zhuǎn)為使用絕對URL形式,服務器必須接受請求中的絕對URL形式,即使HTTP/1.1客戶端只會在使用代理的請求中發(fā)送它們。”但是,稍后我們會看到,HTTP/2并未徹底解決此問題,而是使用:authority偽首部字段替換Host首部(請參閱第4章)。
持久連接(也就是KEEP-ALIVE)
HTTP中的另外一個被很多HTTP/1.0服務器所支持的重大更新是持久連接,但是它沒被包含在HTTP/1.0的規(guī)范中。起初,HTTP僅僅是一個請求-響應協(xié)議。客戶端打開連接,請求資源,獲得響應,然后斷開連接。隨著互聯(lián)網(wǎng)的媒體內(nèi)容變得更加豐富,關閉連接被證明是一種浪費性能的行為。顯示一個頁面需要多個資源,所以關閉連接之后還要重新打開它,這導致了不必要的延遲。這個問題被一個新的Connection首部解決了,這個HTTP首部可以隨著HTTP/1.0的請求被發(fā)送。通過指定此首部值為Keey-Alive,客戶端可以要求服務器保持連接打開,以支持發(fā)送更多的請求:

服務器像往常一樣響應,但如果它支持持久連接,它會在響應中包含一個Connection: Keep-Alive首部:

這個響應告訴客戶端,在發(fā)送完響應之后,馬上就可以在同一個連接上發(fā)送一個新的請求,所以服務器不用每次都關閉再重新打開連接。當使用持久連接時,想要知道響應何時完成可能會更困難。對于非持久連接,關閉連接是一個表明服務器已經(jīng)完成了發(fā)送的好信號!所以,必須使用Content-Length首部來定義消息響應體的長度,以便當整個消息體傳輸完成后,客戶端可以發(fā)送一個新請求。
客戶端或服務器可以在任何時候關閉HTTP連接。關閉可能會意外發(fā)生(由于網(wǎng)絡連接錯誤)或有意為之(例如,如果暫時不使用連接,那么服務器可以關閉連接以釋放資源供其他連接使用)。因此,即使使用持久連接,客戶端和服務器也應該監(jiān)視連接并處理意外關閉的連接。一些請求會使情況變得更復雜。例如,你在電子商務網(wǎng)站上結(jié)賬,你不會想要重復發(fā)起請求。
HTTP/1.1不僅將持久連接添加到文檔標準中,還將其作為默認行為。即使響應中沒有Connection:Keep-Alive首部,也可以假定任何HTTP/1.1連接都使用持久連接。如果服務器確實想要關閉連接,無論出于何種原因,則它必須在響應中顯式包含Connection:close HTTP首部:

我們在本章前面的Telnet示例中談到了這個問題。現(xiàn)在可以使用Telnet再次發(fā)送以下內(nèi)容:
? 沒有Connection:Keep-Alive首部的HTTP/1.0請求。你應該可以看到,在發(fā)送響應后服務器自動關閉連接。
? 相同的HTTP/1.0請求,但具有Connection:Keep-Alive首部。你應該可以看到,連接保持打開狀態(tài)。
? 一個HTTP/1.1請求,帶或不帶Connection:Keep-Alive首部。你應該可以看到,在默認情況下連接保持打開狀態(tài)。
對于HTTP/1.1客戶端,包含Connection:Keep-Alive首部的請求并不罕見,而且它還是默認值。同樣,服務器有時會在HTTP/1.1響應中包含此首部,盡管這是不必要的。
在此基礎上,HTTP/1.1增加了管道的概念,因此應該可以通過同一個持久連接發(fā)送多個請求并按順序獲取響應。例如,如果Web瀏覽器正在處理HTML文檔,并且發(fā)現(xiàn)需要CSS文件和JavaScript文件,它應該能夠?qū)⑦@些文件的請求一起發(fā)送,并按順序獲取響應,而不需要等待第一個請求響應完成后才發(fā)出第二個請求。下面是一個例子:

由于某些原因(見第2章),管道化并沒有流行起來,并且客戶端(瀏覽器)和服務器對管道化的支持都很差。因此,雖然持久連接允許在同一個TCP上順序發(fā)出多個請求,這也是一個很好的性能改進,但大多數(shù)HTTP/1.1的實現(xiàn)仍然是遵循請求響應再請求再響應的模式的。當一個請求被處理時,HTTP連接被阻塞,不能用于其他請求。
其他新功能
HTTP/1.1引入了很多其他的新功能,包含:
? 除了在HTTP/1.0中定義的GET、POST和HEAD方法之外,HTTP/1.1又定義了新的方法,如PUT、OPTIONS和比較少見的CONNECT、TRACE及DELETE。
? 更好的緩存方法。這些方法允許服務器指示客戶端將資源(例如CSS文件)存儲在瀏覽器的緩存中,以便在以后需要時重復使用。在HTTP/1.1中引入的Cache-Control HTTP首部比HTTP/1.0中的Expires首部的選項更多。
- HTTP cookies,允許HTTP維護狀態(tài)。
- 引入字符集(如本章的一些例子所示),在HTTP響應中新增語言選項。
- 支持代理。
- 支持權(quán)限驗證。
- 新的狀態(tài)碼。
- 尾隨首部(在4.3.3節(jié)中討論)。
HTTP協(xié)議不斷添加新的首部以進一步擴展功能,其中許多是出于性能或安全原因。HTTP/1.1規(guī)范并未將HTTP/1.1固化,其鼓勵定義新的首部,甚至還使用一個章節(jié)專門討論如何定義和記錄首部[20]。正如之前提到的,其中的一些首部是出于安全原因添加的,網(wǎng)站用它們來告訴Web瀏覽器打開某些可選的安全保護,這樣服務端就不必額外實現(xiàn)安全相關的功能(除了發(fā)送這些響應首部的功能)。曾經(jīng)有一個慣例,是在這些首部中包含一個X-來表明它們沒有被正式標準化(X-Content-Type、X-Frame-Options或X-XSS-Protection),但這個約定已經(jīng)不推薦使用了[21],這就導致新的實驗性首部很難與HTTP/1.1規(guī)范中的首部區(qū)分開來。通常,這些首部都有自己的RFC標準文檔(Content-Security-Policy[22]、Strict-Transport- Security[23]等)。
- 精通Oracle核心技術與項目實戰(zhàn)
- 文心一言從新手到高手(寫作+繪畫+教育+編程+助手)
- 網(wǎng)絡演算:互聯(lián)網(wǎng)確定性排隊系統(tǒng)理論
- Protel 99SE常用功能與應用實例精講
- HTTP/2 in Action 中文版
- 大學計算機應用基礎(Windows 7+Office 2013)
- 大學計算機基礎實踐教程(第2版)
- 網(wǎng)絡組建的工作過程與任務
- 快意編程:Ext JS Web開發(fā)技術詳解
- 01改變世界:計算機發(fā)展史趣談
- 大學計算機基礎(第2版)
- R語言臨床預測模型實戰(zhàn)
- 云計算安全與隱私
- 思科網(wǎng)絡技術學院教程:IT基礎(第7版)
- 新手學電子相冊制作一點通