🎨 HTTP 協議的前世今生

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"0. 前言","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"你知道當我們在網頁瀏覽器的地址欄中輸入 URL 時,Web 頁面是如何呈現的嗎?","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ad/ad1e5dfe5e8a66941cbf2b312a085cc8.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Web 界面當然不會憑空出來,根據 Web 瀏覽器地址欄中指定的 URL,Web 使用一種名爲 HTTP 的協議作爲規範,完成從客戶端到服務端的一些流程。","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「可以說,Web 是建立在 HTTP 協議上進行通信的」","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"1. HTTP 的誕生","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其實,在 1983 年 3 月之前,互聯網還只屬於少數人,全世界的網民之間的信息是無法共享的。在這一互聯網的黎明時期,HTTP 應運而生。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"歐洲核子研究組織的 Tim Berners-Lee 博士提出了一種能夠讓遠隔兩地的網民共享知識的設想,最初的理念是:藉助多文檔之間相互關聯的超文本(HyperTest),連成可相互參閱的 WWW(World Wide Web,萬維網)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"現在已提出了 3 項 WWW 構建技術,分別是:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"把 SGML(標準通用標記語言)作爲頁面的文本標記語言 HTML","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"作爲文檔傳遞協議的 HTTP","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"指定文檔所在地址的 URL","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"WWW 這一名稱,是 Web 瀏覽器當年用來瀏覽超文本的客戶端應用程序的名稱,現在用來表示這一系列的集合,也可簡稱爲 Web。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2. 什麼是 HTTP","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"說了這麼多,大家只知道 HTTP 很牛逼,對 HTTP 是什麼仍然沒有很直觀的概念。別急,在瞭解什麼是 HTTP 之前,我們有必要知道超文本是什麼。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP 傳輸的內容就是","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「超文本」","attrs":{}},{"type":"text","text":":","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"我們先來理解「文本」:在互聯網早期的時候只是簡單的字符文字,但隨着技術的發展,現在「文本」的涵義已經可以擴展爲圖片、視頻、壓縮包等,在 HTTP 眼裏這些都算做「文本」。","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"再來理解「超文本」:它就是超越了普通文本的文本,它是文字、圖片、視頻等的混合體。最關鍵有「超鏈接」","attrs":{}},{"type":"text","text":",能從一個超文本跳轉到另外一個超文本。","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"OK,下面我們正式介紹什麼是 HTTP?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「HTTP:超文本傳輸協議」","attrs":{}},{"type":"text","text":"(HyperText Transfer Protocol)是當今互聯網上應用最爲廣泛的一種網絡協議。所有的 WWW(萬維網) 文件都必須遵守這個標準。","attrs":{}},{"type":"text","marks":[{"type":"underline","attrs":{}}],"text":"HTTP 和 TCP/IP 協議簇中的衆多協議一樣,用於客戶端和服務器端之間的通信","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/45/45afee5358d809b3e001241989e5c44b.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"3. 駐足不前的 HTTP","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"至今被世人廣泛使用的 HTTP 協議,仍然是 20 多年前的版本。也就是說,作爲 Web 文檔傳輸協議的 HTTP,它的版本幾乎沒有更新,從另一方面來說,前人的智慧真的牛逼 👍","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「HTTP/0.9」","attrs":{}},{"type":"text","text":":HTTP 於 1990 年問世,","attrs":{}},{"type":"text","marks":[{"type":"underline","attrs":{}}],"text":"功能簡陋,僅支持 GET 請求方式,並且僅能訪問 HTML 格式的資源","attrs":{}},{"type":"text","text":"。那時的 HTTP 並沒有作爲正式的標準被建立,因此被被稱爲 HTTP 0.9。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「HTTP/1.0」","attrs":{}},{"type":"text","text":":1996 年 5 月 HTTP 正式作爲標準被公佈,版本號爲 HTTP 1.0。","attrs":{}},{"type":"text","marks":[{"type":"underline","attrs":{}}],"text":"在 0.9 版本上做了進步,增加了請求方式 POST 和 HEAD;不再侷限於 0.9 版本的 HTML 格式,根據 Content-Type 可以支持多種數據格式...... 需要注意的是:1.0 版本的工作方式是短連接","attrs":{}},{"type":"text","text":"。雖說 HTTP/1.0 是初期標準,但該協議標準至今仍然在被廣泛使用。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「HTTP/1.1」","attrs":{}},{"type":"text","text":":1997 年公佈的 HTTP 1.1 是目前主流的 HTTP 協議版本。當年的 HTTP 協議的出現主要是爲了解決文本傳輸的難題,現在的 HTTP 早已超出了 Web 這個框架的侷限,被運用到了各種場景裏。當然,","attrs":{}},{"type":"text","marks":[{"type":"underline","attrs":{}}],"text":"1.1 版本的最大變化,就是引入了長連接以及流水線機制(管道機制)","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏面出現的各種專有名詞大家留個印象就行,下文會逐漸講解。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"4. 區分 URL 和 URI","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"與 URI(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「統一資源標識符」","attrs":{}},{"type":"text","text":") 相比,大家應該更熟悉 URL(Uniform Resource Location,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「統一資源定位符」","attrs":{}},{"type":"text","text":"),URL 就是我們使用 Web 瀏覽器訪問 Web 頁面時需要輸入的網頁地址。比如 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"http://baidu.com","attrs":{}}],"attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"URI 是 Uniform Resource Identifier 的縮寫,RFC 2386 分別對這三個單詞進行如下定義:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Uniform:統一規定的格式可方便處理多種不同類型的資源","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Resource:資源的定義是可標識的任何東西。不僅可以是單一的,也可以是一個集合","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Identifier:標識可標識的對象。也稱爲標識符","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"綜上,URI 就是由某個協議方法表示的資源的定位標識符。比如說,採用 HTTP 協議時,協議方案就是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"http","attrs":{}}],"attrs":{}},{"type":"text","text":",除此之外,還有 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ftp","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"telnet","attrs":{}}],"attrs":{}},{"type":"text","text":" 等,標準的 URI 協議方法有 30 種左右。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"URI 有兩種格式,相對 URI 和絕對 URI。","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「相對 URI」","attrs":{}},{"type":"text","text":":指從瀏覽器中基本 URI 處指定的 URL,形如 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"/user/logo.png","attrs":{}}],"attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「絕對 URI」","attrs":{}},{"type":"text","text":":使用涵蓋全部必要信息","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/6e/6e23a399114ef9efc63e74810c0d844a.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"總結來說:","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「URI 用字符串標識某一處互聯網資源,而 URL 標識資源的地點(互聯網上所處的位置),可見 URL 是 URI 的子集」","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"5. HTTP 請求和響應","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP 協議規定,在兩臺計算機之間使用 HTTP 協議進行通信時,在一條通信線路上必定有一端是客戶端,另一端則是服務端。","attrs":{}},{"type":"text","marks":[{"type":"underline","attrs":{}}],"text":"當在瀏覽器中輸入網址訪問某個網站時, 你的瀏覽器(客戶端)會將你的請求封裝成一個 HTTP 請求發送給服務器站點,服務器接收到請求後會組織響應數據封裝成一個 HTTP 響應返回給瀏覽器","attrs":{}},{"type":"text","text":"。換句話說,肯定是先從客戶端開始建立通信的,服務器端在沒有接收到請求之前不會發送響應。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/1c/1c3c3fffc19832c08d1293add63571d1.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下面我們詳細分析一下 HTTP 的請求報文和響應報文","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"① HTTP 請求報文","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP 請求報文由 3 大部分組成:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1)請求行(必須在 HTTP 請求報文的第一行)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2)請求頭(從第二行開始,到第一個空行結束。請求頭和請求體之間存在一個空行)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3)請求體(通常以鍵值對 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"{key:value}","attrs":{}}],"attrs":{}},{"type":"text","text":"方式傳遞數據)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"舉個請求報文的例子:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/42/426f7549c7316f11592de05dbaa4fd25.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"請求行開頭的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"POST","attrs":{}}],"attrs":{}},{"type":"text","text":" 表示請求訪問服務器的類型,稱爲方法(method)。隨後的字符串 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"/form/login","attrs":{}}],"attrs":{}},{"type":"text","text":" 指明瞭請求訪問的資源對象,也叫做請求 URI(request-URI)。最後的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"HTTP/1.1","attrs":{}}],"attrs":{}},{"type":"text","text":" 即 HTTP 的版本號,用來提示客戶端使用的 HTTP 協議功能。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"綜上來看,這段請求的意思就是:請求訪問某臺 HTTP 服務器上的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"/form/login","attrs":{}}],"attrs":{}},{"type":"text","text":" 頁面資源,並附帶參數 name = veal、age = 37。","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#6a737d","name":"user"}},{"type":"strong","attrs":{}}],"text":"❝","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#6a737d","name":"user"}}],"text":"注意,無論是 HTTP 請求報文還是 HTTP 響應報文,請求頭/響應頭和請求體/響應體之間都會有一個","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#6a737d","name":"user"}},{"type":"strong","attrs":{}}],"text":"「空行」","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#6a737d","name":"user"}}],"text":",且請求體/響應體並不是必須的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#6a737d","name":"user"}}],"text":"❞","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"HTTP 請求方法","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"請求行中的方法的作用在於可以指定請求的資源按照期望產生某種行爲,即","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「使用方法給服務器下命令」","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"包括(HTTP 1.1):","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"GET","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"POST","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"PUT","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"HEAD","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"DELETE","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"OPTIONS","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"CONNECT","attrs":{}}],"attrs":{}},{"type":"text","text":"、","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"TRACE","attrs":{}}],"attrs":{}},{"type":"text","text":"。當然,我們在開發中最常見也最常使用的就只有前面三個。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「GET 獲取資源」","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"GET 方法用來請求訪問已被 URI 識別的資源。指定的資源經服務器端解析後返回響應內容","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/50/50a91af1c02aac11071db5a2f6358c43.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 GET 方法請求-響應的例子:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/2b/2b2421fbc377c232688d2cad243aa889.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「POST 傳輸實體主體」","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"POST 主要用來傳輸數據,而 GET 主要用來獲取資源。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/2b/2b9b9f420011077b9ce04bf737068ca8.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 POST 方法請求-響應的例子:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8e/8ec09663ceef4f9dc2613e29579dc2b4.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「PUT 傳輸文件」","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"PUT 方法用來傳輸文件,由於自身","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「不帶驗證機制,任何人都可以上傳文件」","attrs":{}},{"type":"text","text":",因此存在安全性問題,一般不使用該方法。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/63/63bd137ab55f6981502dfdc3d0fff077.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 PUT 方法請求-響應的例子:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d3/d3b36a752bac31e9b3507983cf463c04.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「HEAD 獲取報文首部」","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"和 GET 方法類似,但是不返回報文實體主體部分。主要用於確認 URI 的有效性以及資源更新的日期時間等。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ff/ffa187df5541b61bdbea7b953fbef56d.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 HEAD 方法請求-響應的例子:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ba/ba1c8b5b0158ca9a69f191afa0857f95.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"5)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「DELETE 刪除文件」","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"與 PUT 功能相反,用來刪除文件,並且同樣不帶驗證機制,按照請求 URI 刪除指定的資源。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/77/777613c5d59178e347862715aa7eabd9.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 DEELTE 方法請求-響應的例子:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/62/62d450f2272aac214a4a6e93b73f9e5c.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"6)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「OPTIONS 查詢支持的方法」","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用於","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「獲取當前 URI 所支持的方法」","attrs":{}},{"type":"text","text":"。若請求成功,會在 HTTP 響應頭中包含一個名爲 “","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Allow","attrs":{}}],"attrs":{}},{"type":"text","text":"” 的字段,值是所支持的方法,如 “GET, POST”。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/75/753d93bf5442cf84e3e0c3d48be089d4.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用 OPTIONS 方法請求-響應的例子:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a9/a9d479549314da17c12d2812a2eef6ba.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"7)..........","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"HTTP 請求頭","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"請求頭用於補充請求的附加信息、客戶端信息、對響應內容相關的優先級等內容。以下列出常見請求頭:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「Referer」","attrs":{}},{"type":"text","text":":表示這個請求是從哪個 URI 跳過來的。比如說通過百度來搜索淘寶網,那麼在進入淘寶網的請求報文中,Referer 的值就是:www.baidu.com。如果是直接訪問就不會有這個頭。這個字段通常用於防盜鏈。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/64/64af79ae12dcc0f337756bd3b15d312f.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「Accept」","attrs":{}},{"type":"text","text":":告訴服務端,該請求所能支持的響應數據類型。(對應的,HTTP 響應報文中也有這樣一個類似的字段 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Content-Type","attrs":{}}],"attrs":{}},{"type":"text","text":",用於表示服務端發送的數據類型,如果 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Accept","attrs":{}}],"attrs":{}},{"type":"text","text":" 指定的類型和服務端返回的類型不一致,就會報錯)","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/8d/8df6f0f7a3151d54e05b8b39e4fd5b37.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上圖中的 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"text/plain;q = 0.3","attrs":{}}],"attrs":{}},{"type":"text","text":" 表示對於 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"text/plain","attrs":{}}],"attrs":{}},{"type":"text","text":" 媒體類型的數據優先級/權重爲 0.3(q 的範圍 0 ~ 1)。不指定權重的,默認爲 1.0。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據格式類型如下圖:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/38/3829d91299c4f2681dc39fdb1e0e1eef.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「Host」","attrs":{}},{"type":"text","text":":告知服務器請求的資源所處的互聯網主機名和端口號。該字段是 HTTP/1.1 規範中唯一一個必須被 包含在請求頭中的字段。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「Cookie」","attrs":{}},{"type":"text","text":":客戶端的 Cookie 就是通過這個報文頭屬性傳給服務端的!","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"5)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「Connection」","attrs":{}},{"type":"text","text":":表示客戶端與服務連接類型;Keep-Alive 表示持久連接,close 已關閉","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"6)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「Content-Length」","attrs":{}},{"type":"text","text":":請求體的長度","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"7)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「Accept-Language」","attrs":{}},{"type":"text","text":":瀏覽器通知服務器,瀏覽器支持的語言","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"8)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「Range」","attrs":{}},{"type":"text","text":":對於只需獲取部分資源的範圍請求,包含首部字段 Range 即可告知服務器資源的指定範圍","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"9)......","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"② HTTP響應報文","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP的響應報文也由三部分組成:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"響應行(必須在 HTTP 響應報文的第一行)","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"響應頭(從第二行開始,到第一個空行結束。響應頭和響應體之間存在一個空行)","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"響應體","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/98/98302c35fe9211b3f19c9654d70018e1.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在響應行開頭的 HTTP 1.1 表示服務器對應的 HTTP 版本。緊隨的 200 OK 表示請求的處理結果的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「狀態碼」","attrs":{}},{"type":"text","text":"和","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「原因短語」","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"HTTP 狀態碼","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「HTTP 狀態碼負責表示客戶端 HTTP 請求的的返回結果、標記服務器端處理是否正常、通知出現的錯誤等工作」","attrs":{}},{"type":"text","text":"。(重中之重!!!,和我們日常開發息息相關)","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c0/c09c2a90d8e67053d6fab2b6a10b1bb2.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"狀態碼由 3 位數字組成,第一個數字定義了響應的類別:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"bgcolor","attrs":{"color":"#f0f0f0","name":"user"}},{"type":"strong","attrs":{}}],"text":"類別原因短語","attrs":{}},{"type":"text","text":"1xxInformational 信息性狀態碼接收的請求正在處理","attrs":{}},{"type":"text","marks":[{"type":"bgcolor","attrs":{"color":"#F8F8F8","name":"user"}}],"text":"2xxSuccess 成功狀態碼請求正常處理完畢","attrs":{}},{"type":"text","text":"3xxRedirection 重定向狀態碼需要進行附加操作以完成請求","attrs":{}},{"type":"text","marks":[{"type":"bgcolor","attrs":{"color":"#F8F8F8","name":"user"}}],"text":"4xxClient Error 客戶端錯誤狀態碼服務器無法處理請求","attrs":{}},{"type":"text","text":"5xxServer Error 服務器錯誤狀態碼服務器處理請求出錯","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"🔶 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「2xx」","attrs":{}},{"type":"text","text":":請求正常處理完畢","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"200 OK","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":客戶端請求成功","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/43/432a511a288e88b594ccc9cdf70d1fef.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"204 No Content","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":無內容。服務器成功處理,但未返回內容。一般用在只是客戶端向服務器發送信息,而服務器不用向客戶端返回什麼信息的情況。不會刷新頁面。","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/3c/3c3f11663d5fc0211be47c70f88adebb.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"206 Partial Content","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":服務器已經完成了部分 GET 請求(客戶端進行了範圍請求)。響應報文中包含 Content-Range 指定範圍的實體內容","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/90/9061543270a27fbbe975f235a0535834.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"🔶 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「3xx」","attrs":{}},{"type":"text","text":":需要進行附加操作以完成請求(重定向)","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"301 Moved Permanently","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":永久重定向,表示請求的資源已經永久的搬到了其他位置。","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"302 Found","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":臨時重定向,表示請求的資源臨時搬到了其他位置","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"303 See Other","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":臨時重定向,應使用GET定向獲取請求資源。303功能與302一樣,區別只是303明確客戶端應該使用GET訪問","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"304 Not Modified","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":表示客戶端發送附帶條件的請求(GET方法請求報文中的IF…)時,條件不滿足。返回304時,不包含任何響應主體。雖然304被劃分在3XX,但和重定向一毛錢關係都沒有","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"307 Temporary Redirect","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":臨時重定向,和302有着相同含義。POST不會變成GET","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"🔶 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「4xx」","attrs":{}},{"type":"text","text":":客戶端錯誤","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"400 Bad Request","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":客戶端請求有語法錯誤,服務器無法理解。","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"401 Unauthorized","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":請求未經授權,這個狀態代碼必須和 WWW-Authenticate 報頭域一起使用。","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"403 Forbidden","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":服務器收到請求,但是拒絕提供服務","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"404 Not Found","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":請求資源不存在。比如,輸入了錯誤的 URL","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"415 Unsupported media type","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":不支持的媒體類型","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"🔶 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「5xx」","attrs":{}},{"type":"text","text":":服務器端錯誤,服務器未能實現合法的請求。","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"500 Internal Server Error","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":服務器發生不可預期的錯誤。","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"503 Server Unavailable","attrs":{}}],"marks":[{"type":"strong"}],"attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":":服務器當前處於超負載或正在停機維護,暫時不能處理客戶端的請求,一段時間後可能恢復正常","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"HTTP 響應頭","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"響應頭也是用鍵值對 k:v,用於補充響應的附加信息、服務器信息,以及對客戶端的附加要求等。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d9/d99715fc5200398ffbba2d4795b19a80.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏着重說明一下 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Location","attrs":{}}],"attrs":{}},{"type":"text","text":" 這個字段,可以將響應接收方引導至與某個 URI 位置不同的資源。通常來說,該字段會配合 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"3xx:Redirection","attrs":{}}],"attrs":{}},{"type":"text","text":" 的響應,提供重定向的 URI。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/0a/0a203ea03c88798e21db826f44c25fef.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"6. HTTP 連接管理","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"① 短連接(非持久連接)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在 HTTP 協議的初始版本(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「HTTP/1.0」","attrs":{}},{"type":"text","text":")中,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「客戶端和服務器每進行一次 HTTP 會話,就建立一次連接,任務結束就中斷連接」","attrs":{}},{"type":"text","text":"。當客戶端瀏覽器訪問的某個 HTML 或其他類型的 Web 頁中包含有其他的 Web 資源(如JavaScript 文件、圖像文件、CSS文件等),每遇到這樣一個 Web 資源,瀏覽器就會重新建立一個 HTTP 會話。這種方式稱爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「短連接」","attrs":{}},{"type":"text","text":"(也稱","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「非持久連接」","attrs":{}},{"type":"text","text":")。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"也就是說每次 HTTP 請求都要重新建立一次連接。由於 HTTP 是基於 TCP/IP 協議的,所以連接的每一次建立或者斷開都需要 TCP 三次握手或者 TCP 四次揮手的開銷。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/88/88a0fdb088ff03109fdd54aa8f58b2be.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"顯然,這種方式存在巨大的弊端。比如訪問一個包含多張圖片的 HTML 頁面,每請求一張圖片資源就會造成無謂的 TCP 連接的建立和斷開,大大增加了通信量的開銷","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/cf/cf9fc2fcea6b0dc8cb488fe49f1c5c02.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"② 長連接(持久連接)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「HTTP/1.1」","attrs":{}},{"type":"text","text":" 起,默認使用","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「長連接」","attrs":{}},{"type":"text","text":"也稱","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「持久連接 keep-alive」","attrs":{}},{"type":"text","text":"。使用長連接的 HTTP 協議,會在響應頭加入這行代碼:","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Connection:keep-alive","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在使用長連接的情況下,當一個網頁打開完成後,客戶端和服務器之間用於傳輸 HTTP 數據的 TCP 連接不會關閉,客戶端再次訪問這個服務器時,會繼續使用這一條已經建立的連接。","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「Keep-Alive 不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如 Apache)中設定這個時間」","attrs":{}},{"type":"text","text":"。實現長連接需要客戶端和服務端都支持長連接。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/9e/9e40ea6c628cffe75d9b9b48720658cc.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#6a737d","name":"user"}},{"type":"strong","attrs":{}}],"text":"❝","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#6a737d","name":"user"}}],"text":"HTTP 協議的長連接和短連接,實質上是 TCP 協議的長連接和短連接。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#6a737d","name":"user"}}],"text":"❞","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"③ 流水線(管線化)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"默認情況下,HTTP 請求是按順序發出的,下一個請求只有在當前請求收到響應之後纔會被髮出。由於受到網絡延遲和帶寬的限制,在下一個請求被髮送到服務器之前,可能需要等待很長時間。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"持久連接使得多數請求以","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「流水線」","attrs":{}},{"type":"text","text":"(管線化 pipeline)方式發送成爲可能,即在","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「同一條持久連接上連續發出請求,而不用等待響應返回後再發送」","attrs":{}},{"type":"text","text":",這樣就可以做到同時","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「並行」","attrs":{}},{"type":"text","text":"發送多個請求,而不需要一個接一個地等待響應了。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/82/82a85c800be15e85d852c7cdf2096bcb.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"7. 無狀態的 HTTP","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTTP 協議是無狀態協議。也就是說他不對之前發生過的請求和響應的狀態進行管理,即無法根據之前的狀態進行本次的請求處理。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這樣就會帶來一個明顯的問題,如果 HTTP 無法記住用戶登錄的狀態,那豈不是每次頁面的跳轉都會導致用戶需要再次重新登錄?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當然,不可否認,無狀態的優點也很顯著,由於不必保存狀態,自然就減少了服務器的 CPU 及內存資源的消耗。另一方面,正式由於 HTTP 簡單,所以纔會被如此廣泛應用。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/5d/5de43181e7b1cbb6711d58b37ecf33eb.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這樣,在保留無狀態協議這個特徵的同時,又要解決無狀態導致的問題。方案有很多種,其中比較簡單的方式就是使用 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「Cookie」","attrs":{}},{"type":"text","text":" 技術。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Cookie","attrs":{}}],"attrs":{}},{"type":"text","text":" 通過在請求和響應報文中寫入 Cookie 信息來控制客戶端的狀態。具體來說,Cookie 會根據從服務器端發送的響應報文中的一個叫作 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Set-Cookie","attrs":{}}],"attrs":{}},{"type":"text","text":" 的首部字段信息,通知客戶端保存 Cookie。當下次客戶端再往服務器發送請求時,客戶端會自動在請求報文中加入 Cookie 值發送出去。服務器端收到客戶端發來的 Cookie 後,會去檢查究竟是哪一個客戶端發來的連接請求,然後對比服務器上的記錄,最後得到之前的狀態信息。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"形象來說,在客戶端第一次請求後,服務器會下發一個裝有客戶信息的身份證,後續客戶端請求服務器的時候,帶上身份證,服務器就能認得了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下圖展示了發生 Cookie 交互的情景:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「沒有 Cookie 信息狀態下的請求」","attrs":{}},{"type":"text","text":":","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d5/d54aaaf54c25263f07477a082eb2d3b6.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對應的 HTTP 請求報文(沒有 Cookie 信息的狀態)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"GET /reader/ HTTP/1.1","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#abb2bf","name":"user"}},{"type":"bgcolor","attrs":{"color":"#282c34","name":"user"}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Host: baidu.com","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"* 首部字段沒有 Cookie 的相關信息","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對應的 HTTP 響應報文(服務端生成 Cookie 信息)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"HTTP/1.1 200 OK","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#abb2bf","name":"user"}},{"type":"bgcolor","attrs":{"color":"#282c34","name":"user"}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Date: Thu, 12 Jul 2020 15:12:20 GMT","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Server: Apache","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Content-Type: text/plain; charset=UTF-8","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2)","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「第 2 次以後的請求(存有 Cookie 信息狀態)」","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/dc/dc3a39984b227c9838e40ffba9bc26fb.png","alt":"","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對應的 HTTP 請求報文(自動發送保存着的 Cookie 信息)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"GET /image/ HTTP/1.1","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#abb2bf","name":"user"}},{"type":"bgcolor","attrs":{"color":"#282c34","name":"user"}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Host: baidu.com","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Cookie: sid=1342077140226","attrs":{}}],"attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"8. HTTP 斷點續傳","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所謂斷點續傳指的是下載傳輸文件可以中斷,之後重新下載時可以接着中斷的地方開始下載,而不必從頭開始下載。斷點續傳需要客戶端和服務端都支持。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這是一個非常常見的功能,原理很簡單,其實就是 HTTP 請求頭中的字段 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Range","attrs":{}}],"attrs":{}},{"type":"text","text":" 和響應頭中的字段 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Content-Range","attrs":{}}],"attrs":{}},{"type":"text","text":" 的簡單使用。客戶端一塊一塊的請求數據,最後將下載回來的數據塊拼接成完整的數據。打個比方,瀏覽器請求服務器上的一個服務,所發出的請求如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"假設服務器域名爲 www.baidu.com,文件名爲 down.zip。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"GET /down.zip HTTP/1.1 ","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#abb2bf","name":"user"}},{"type":"bgcolor","attrs":{"color":"#282c34","name":"user"}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms- ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"excel, application/msword, application/vnd.ms-powerpoint, */* ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Accept-Language: zh-cn ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Accept-Encoding: gzip, deflate ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0) ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Connection: Keep-Alive ","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務器收到請求後,按要求尋找請求的文件,提取文件的信息,然後返回給瀏覽器,返回信息如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"200 ","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#abb2bf","name":"user"}},{"type":"bgcolor","attrs":{"color":"#282c34","name":"user"}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Content-Length=106786028 ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Accept-Ranges=bytes ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Date=Mon, 30 Apr 2001 12:56:11 GMT ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ETag=W/","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#98c379","name":"user"}}],"text":"\"02ca57e173c11:95b\"","attrs":{}},{"type":"text","text":" ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Content-Type=application/octet-stream ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Server=Microsoft-IIS/5.0 ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Last-Modified=Mon, 30 Apr 2001 12:56:11 GMT ","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"OK,那麼既然要斷點續傳,客戶端瀏覽器請求服務器的時候要多加一條信息 — 從哪裏開始請求數據。 比如要求從 2000070 字節開始:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"GET /down.zip HTTP/1.0 ","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#abb2bf","name":"user"}},{"type":"bgcolor","attrs":{"color":"#282c34","name":"user"}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"User-Agent: NetFox ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"RANGE: bytes=2000070- ","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 ","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"仔細看一下就會發現多了一行 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"RANGE: bytes=2000070-","attrs":{}}],"attrs":{}},{"type":"text","text":"。這一行的意思就是告訴服務器 down.zip 這個文件從 2000070 字節開始傳,前面的字節不用傳了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"服務器收到這個請求以後,返回的信息如下:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"206","attrs":{}}],"marks":[{"type":"color","attrs":{"color":"#abb2bf","name":"user"}},{"type":"bgcolor","attrs":{"color":"#282c34","name":"user"}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Content-Length=106786028","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Content-Range=bytes 2000070-106786027/106786028","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Date=Mon, 30 Apr 2001 12:55:20 GMT","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"ETag=W/","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#98c379","name":"user"}}],"text":"\"02ca57e173c11:95b\"","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Content-Type=application/octet-stream","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Server=Microsoft-IIS/5.0","attrs":{}}],"attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Last-Modified=Mon, 30 Apr 2001 12:55:20 GMT","attrs":{}}],"attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"和前面服務器返回的信息比較一下,就會發現增加了一行: ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Content-Range=bytes 2000070-106786027/106786028","attrs":{}}],"attrs":{}},{"type":"text","text":"。返回的代碼也改爲 206 了,而不再是 200 了。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"9. HTTP 的缺點","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"到現在爲止,我們已經瞭解到了 HTTP 具有相當優秀和方便的一面,然後,事務皆有兩面性,他也是有不足之處的:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"通信使用明文(不加密),內容可能被「竊聽」","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"不驗證通信對方的身份,因此有可能遭遇「僞裝」","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"無法證明報文的完整性,所以有可能被「篡改」","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這些問題不僅在 HTTP 上出現,其他未加密的協議中也存在類似問題,爲了解決 HTTP 的痛點,HTTPS 應用而生,說白了 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"「HTTP + 加密 + 認證 + 完整性保護就是 HTTPS 協議」","attrs":{}},{"type":"text","text":",關於 HTTPS 協議的內容也非常之多且重要,後續會單開一篇文章進行講解。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"🎉 關注公衆號 | 飛天小牛肉,即時獲取更新","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"博主東南大學研一在讀,利用課餘時間運營一個","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"公衆號『 飛天小牛肉 』","attrs":{}},{"type":"text","text":",專注分享計算機基礎(數據結構 + 算法 + 計算機網絡 + 數據庫 + 操作系統 + Linux)、Java 基礎和麪試指南的相關原創技術好文。本公衆號的目的就是","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"讓大家可以快速掌握重點知識,有的放矢","attrs":{}},{"type":"text","text":"。關注公衆號,第一時間獲取文章更新,與小牛肉一起成長吧!","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/0d/0d993720bb1afd13bdbbe959ed8a55d0.png","alt":null,"title":"","style":[{"key":"width","value":"25%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"並推薦個人維護的開源教程類項目: ","attrs":{}},{"type":"link","attrs":{"href":"https://gitee.com/veal98/CS-Wiki","title":null},"content":[{"type":"text","text":"CS-Wiki(Gitee 推薦項目,現已 0.9k star)","attrs":{}}],"marks":[{"type":"strong"}]},{"type":"text","text":", 面向全棧,致力於構建完善的知識體系(數據結構、計算機網絡、操作系統、算法、數據庫、設計模式、Java 技術棧、機器學習、深度學習、強化學習等)。相比公衆號,本倉庫擁有更加健全的知識體系,歡迎各位小夥伴前來 star ~ 😊","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章