HTTP 的原理和工作機制(一)

HTTP 是什么?

Hyper Text Transfer Protocol 超文本傳輸協(xié)議,是一種 Client 和 Server 之間請求和應(yīng)答的標(biāo)準(zhǔn),目的是更高效的進(jìn)行網(wǎng)絡(luò)傳輸。

HTTP 工作方式

用戶最直觀的感受就是瀏覽器地址欄鍵入地址->回車->看到瀏覽器呈現(xiàn)的網(wǎng)頁,這個過程簡單的流程就是:
瀏覽器發(fā)送請求到服務(wù)器,服務(wù)器響應(yīng)請求,瀏覽器通過渲染引擎渲染網(wǎng)頁結(jié)果,渲染引擎也就是瀏覽器的內(nèi)核。

image.png

示例地址:https://twitter.com/shaddeen_/followers

shaddeen,是小眾音樂播放器 Loud 和 SmartPlayer 的作者。

所以在這個從按下回車到直觀看到界面的過程就簡單的概括為 3 步:

  1. 請求
  2. 響應(yīng)
  3. 渲染

在請求的過程中,瀏覽器地址欄的 URL 轉(zhuǎn)化成 HTTP 報文進(jìn)行發(fā)送,一個 URL 大致分為三個部分:
https/http: 協(xié)議類型、twitter.com 服務(wù)器地址shaddeen_/followers 路徑(path)。

請求發(fā)送的形式就變成:

GET /shaddeen_/followers HTTP/1.1
Host: twitter.com

在這個過程中,兩個極其重要的角色也就出現(xiàn)了:Request 和 Response。

Request 報文格式

簡易的 Request 報文格式如下:

GET /shaddeen_/followers HTTP/1.1
Host: twitter.com

GET /shaddeen_/followers HTTP/1.1為一個請求行,分三個部分:

  • GET 為 請求 method;
  • /shaddeen_/followers 為 path,負(fù)責(zé)定位;
  • HTTP/1.1 為 HTTP Version,現(xiàn)在絕大多數(shù)的瀏覽器的網(wǎng)頁顯示 HTTP 版本都是 1.1。

Host: twitter.com 為請求 Headers,可為多行(包括更多的內(nèi)容如 Content-Type: text/plain Content-Length: 240)。
另,請求可以加入 Body,可以加入實際的內(nèi)容,該內(nèi)容是服務(wù)器需要處理的。Body 和請求行中的 path 都是和服務(wù)器對接并需要服務(wù)器處理的,但是各自角色的定位并不一樣。

Response 報文格式

Response 的報文同樣也有 Headers 和 Body,相比 Request 無請求行,多了一個狀態(tài)行,例:

狀態(tài)行?
HTTP/1.1 200 OK
Headers?
content-type: application/json; charset=utf-8
cache-control: public, max-age=60, s-maxage=60
vary: Accept, Accept-Encoding
etag: W/"02fjsdarwr080823f"
content-encoding: gzip
Body?
[
    name: "shaddeen_",
    id: "2342242",
    follow_list: [
        ...
    ]
    ...
]

HTTP/1.1 200 OK 亦分為三個部分:

  • HTTP/1.1 HTTP 版本;
  • 200 status code 狀態(tài)碼;
  • OK status message 狀態(tài)信息。

這三部分的組合可以簡單地描述一次請求。

Request Method

  • GET 獲取資源,無 body,簡單的來說就是從網(wǎng)上取東西;
  • POST 增加或修改資源,有 body,要把修改的內(nèi)容放進(jìn) body 里給服務(wù)器進(jìn)行處理;
  • PUT 修改資源, 有 body,它和 GET 有個共同的特點就是冪等(一個冪等操作的特點是其任意多次執(zhí)行所產(chǎn)生的影響均與一次執(zhí)行的影響相同,在這里指多次操作對于服務(wù)器沒有影響)的;
  • DELETE 刪除資源,無 body,同樣具有冪等性;
  • HEAD 幾乎和 GET 是一樣的,區(qū)別在于服務(wù)器返回內(nèi)容的時候不會返回 body,當(dāng)做下載功能的時候通常需要預(yù)先知道該文件有多大或更多的信息,此時 HEAD 通過請求會得到這些信息,然后再進(jìn)行一步處理。

Status Code

作用:對結(jié)果作出類型化描述(如「成功」、「未找到」)。

通常規(guī)范化的狀態(tài)碼有 5 類,分類是為了方便調(diào)試:

  • 1xx: 臨時性消息,通常為 100 和 101。100,表示初始的請求已經(jīng)接受,客戶端可以接著進(jìn)行下面的請求,如上傳一個大文件,在試探性請求服務(wù)器的過程中,會把一些描述信息放進(jìn) Header 中與服務(wù)器溝通試探服務(wù)器是否接受,如服務(wù)器返回 100 則客戶端可以進(jìn)行下面的操作。101 表示服務(wù)器回應(yīng)客戶端「支持 HTTP/2.0」,此時客戶端下一次的請求就可以切換為為 HTTP/2.0,當(dāng)不支持 HTTP/2.0 的時候會返回 200,那么客戶端下一次請求則使用 HTTP/1.1 ;
  • 2xx: 成功;
  • 3xx: 重定向,如地址欄鍵入 http://www.google.com ,瀏覽器會重定向到 https://www.google.com ,該過程是一個自動的二次請求過程,就是通過返回的 301 (Moved Permanently 永久性遷移, 302 為臨時遷移,304 表示內(nèi)容沒有改變,F(xiàn)5 重新刷新該網(wǎng)頁)狀態(tài)碼來告訴客戶端重新請求;
  • 4xx: 客戶端(瀏覽器、手機軟件)錯誤,如參數(shù)錯誤,服務(wù)器無法識別該請求,是可以修正的;
  • 5xx: 服務(wù)器錯誤,如資源不足、資源找不到。

Header

作用:Header 描述了 HTTP 消息的元信息 (Meta Data),通俗地說就是描述數(shù)據(jù)的數(shù)據(jù),如:該消息有多長?是什么格式?數(shù)據(jù)有沒有壓縮?返回的數(shù)據(jù)是什么字符集等等。

Host

在前面的例子中,有一個 Host 的字段,它表示服務(wù)器主機地址,但是它不是用來尋址的,尋址的過程在發(fā)送請求之前就已經(jīng)做好了

在發(fā)送請求前,瀏覽器會帶著域名「詢問」 DNS(Domain Name System 域名系統(tǒng)) 目標(biāo) IP 地址,然后 DNS 返回一個或多個 IP 地址,然后通過 IP 地址去尋址,然后發(fā)送報文給目標(biāo)服務(wù)器。

那么為什么在請求 Header 中為什么還要帶上 Host ?

是因為一個服務(wù)器主機下可能有多個虛擬主機或多個子服務(wù)器(多個網(wǎng)站)存在,也就是同樣一個 IP 地址下面會有多個服務(wù)器存在,由于它們對外的 IP 都是一樣的,瀏覽器根據(jù)這個 IP 去請求服務(wù)器,服務(wù)器會無法識別該次請求訪問具體哪個主機,最終得不到正確的響應(yīng),所以需要發(fā)送 Host 附加到 Header 到服務(wù)器。

服務(wù)器地址一般的形式是:域名 + TCP 端口。

Content-Type/Content-Length

描述 Body 的類型和長度。

  • Content-Length:內(nèi)容的長度(字節(jié))

為什么會有 Content-Type 的存在?

是因為請求報文中,可能會攜帶二進(jìn)制非文本數(shù)據(jù),二進(jìn)制數(shù)據(jù)本身是不受限制的,它表示著各種各樣的字節(jié),那么如何表示內(nèi)容字節(jié)結(jié)束?此時 Content-Type 的作用就是表示規(guī)定一個長度,長度范圍內(nèi)讀取數(shù)據(jù),長度過后的數(shù)據(jù),直接扔棄。

  • Content-Type:內(nèi)容的類型

text/html: html 文本,用于瀏覽器頁面響應(yīng)。
application/x-www-form-urlencoded: 普通表單,encode URL 格式,只作用于文本。

表單,可以簡單的理解為:一個要提交的表,是瀏覽器和服務(wù)器溝通的一個格式。通過表單,服務(wù)器會解析本次請求的 Body 內(nèi)容,找對應(yīng)參數(shù)。

multipart/form-data: 多部分形式,一般用于包含二進(jìn)制內(nèi)容的多項內(nèi)容。后面會跟 boundary=----WebKitFormBoundaryxxxxxx,它的作用是用來分界 Body 和 Header 以及 Body 的各個屬性。如修改人物信息的時候,通常會附帶普通的「名字信息」和「頭像圖片」,那么請求格式如下:

POST /users HTTP/1.1
Host: twitter.com
Content-Type: multipart/form-data boundary=----WebKitFormBoundary247HFSSj7fgwj01
Content-Length:2300
------WebKitFormBoundary247HFSSj7fgwj01 // 分界 
Content-Disposition:form-data; name="user_name"http:// user_name 屬性
valentizx
------WebKitFormBoundary247HFSSj7fgwj01 // 分界 
Content-Dispostion: form-data; name="avatar";filename="valentizx.jpg" // avatar 屬性
Content-Type: image/jpeg
SFH72jfoa6GSKHGS....

------WebKitFormBoundary247HFSSj7fgwj0-- // 分界 

分界前面有 6 個 「-」,前兩個「-」表示一個新的屬性的開始,最后一個分界后面有兩個「-」表示結(jié)束。

application/json: json 形式,多用于 Web Api 的響應(yīng)或 PUT/POST 請求
image/jpeg、application/zip ...: 但文件,用于 Web Api 響應(yīng)或 POST/PUT 請求。

Chunked Transfer Encoding 分塊傳輸

當(dāng)一次請求的響應(yīng)數(shù)據(jù)內(nèi)容較大時,為不影響用戶體驗,服務(wù)器通常會返回一個 chunk 單位的數(shù)據(jù)給客戶端,但是服務(wù)器不會告訴 Header 每一個 chunk 具體多長,也就是 Body 長度無法確定,此時 Content-Type 無法使用。于是,新的 Body 格式出現(xiàn):

<length1>
<data1>
<length2>
<data2>
0
 // ?此處有換行位?

明確每一小段(chunk)的長度放到 Header 中,先傳輸 data1,當(dāng) data2 準(zhǔn)備就緒的時候傳輸 data2,直到傳輸 0 + 換行 表示內(nèi)容結(jié)束。

Location

重定向的目標(biāo) URL,一次請求返回 301 的時候,瀏覽器會進(jìn)行重定向到 Location 字段后的地址再進(jìn)行一次請求。

User-Agent

用戶代理,就是指客戶端(Client),網(wǎng)頁會根據(jù)不同的設(shè)備進(jìn)行適配,標(biāo)識憑借就是 User-Agent。

Range/Accept-Range

指定 Body 的內(nèi)容范圍,當(dāng)目標(biāo)服務(wù)器支持分段取內(nèi)容的時候,該字段發(fā)揮作用,其最主要的兩個應(yīng)用點就是:斷點續(xù)傳分段下載。

Cookie/Set-Cookie

發(fā)送 Cookie,設(shè)置 Cookie

Authorization

授權(quán)信息

部分其他 Header

Accept: 客戶端能接受的數(shù)據(jù)類型。如 text/html
Accept-Charset: 客戶端度接受的字符集。如 utf-8
Accept-Encoding: 客戶端接受的壓縮編碼類型。如 gzip
Content-Encoding: 壓縮類型。如 gzip

Cache

Cache 和 Buffer

  • Cache:緩存,表示一塊內(nèi)容可能多次使用,所以這部分內(nèi)容暫時放在緩存區(qū)域中,當(dāng)不用的時候會被回收掉,面向速度;
  • Buffer: 緩沖,工作過程中,上游生產(chǎn)快下游不能及時消費,或者下游暫時無消費,時間段過后會「猛」消費,則需要緩沖機制,提前生產(chǎn)一點存起來供下游使用,面向工作流;

Cache-Control

no-cacheno-store、max-age:

  • no-cache: 服務(wù)器告訴 Client 端,該內(nèi)容可以緩存,但是再次請求的時候服務(wù)器需要知道緩存的內(nèi)容是否失效;
  • no-store: 不許緩存;
  • max-age: 在失效日期內(nèi),Client 端隨意訪問;

Last-Modified

If-Modified-Since: 緩存界面最后的修改時間,請求過程中,服務(wù)器會對比緩存的最后修改時間和真實文件的最后修改時間,如果一致,說明文件沒有改動過,返回 304,否則返回 200 和新的內(nèi)容。

Etag

If-None-Match: 相當(dāng)于 Hash,或者說相當(dāng)于一個指紋,Client 端也可憑借該字段與服務(wù)器「溝通」,對比這個標(biāo)簽,如果不是最新的,則請求最新的,返回 200 顯示新內(nèi)容,如果一致,則 返回 304。

Cache-Control

privatepublic,一次請求的實際過程可能極其復(fù)雜,通過各個節(jié)點,各個網(wǎng)關(guān),private 和 public 就是告訴路上經(jīng)過的這些中間節(jié)點是否需要幫助緩存信息。

? private 并不表示內(nèi)容的私密性,私密性是通過加密機制來實現(xiàn)的,它表示「個性化定制信息」。

REST

REST:對 HTTP 進(jìn)行一種限制,屬于一種架構(gòu)風(fēng)格。

  • Server-Client architecture
  • Statelessness
  • Cacheability
  • Layered system
  • Code on demand
  • Uniform interface
    • Resource identification in requests
    • Resource manipulation through representations
    • Self-descriptive messages
    • Hypermedia as the engine of application state (HATEOAS)

RESTful HTTP

規(guī)范 HTTP 的使用方式,正確的使用 HTTP。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 當(dāng) app 和服務(wù)器進(jìn)行通信的時候,大多數(shù)情況下,都是采用 HTTP 協(xié)議。HTTP 最初是為 web 瀏覽器而定...
    Flysss1219閱讀 1,443評論 0 4
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標(biāo)準(zhǔn)。 注意:講述HT...
    kismetajun閱讀 28,867評論 1 45
  • 組織:中國互動出版網(wǎng)(http://www.china-pub.com/) RFC文檔中文翻譯計劃(http://...
    Palomar閱讀 1,648評論 0 6
  • http協(xié)議有http0.9,http1.0,http1.1和http2三個版本,但是現(xiàn)在瀏覽器使用的是htt...
    一現(xiàn)_閱讀 2,007評論 0 3
  • 通過技術(shù)手段,彌合欠發(fā)達(dá)地區(qū)存在的教育鴻溝,消除教育資源東西部差距,已成為在線教育行業(yè)發(fā)展趨勢和方向。近年來,各地...
    范寧21閱讀 375評論 0 0

友情鏈接更多精彩內(nèi)容