1. 程式人生 > >HTTP(圖解HTTP筆記)

HTTP(圖解HTTP筆記)

在github上發現此資料,貼出連結供大家分享。

https://github.com/CyC2018/Interview-Notebook/blob/master/notes/HTTP.md

  目錄結構:

    

Web 基礎

  • HTTP(HyperText Transfer Protocol,超文字傳輸協議)。
  • WWW(World Wide Web)的三種技術:HTML、HTTP、URL。
  • RFC(Request for Comments,徵求修正意見書),網際網路的設計文件。

URL

  • URI(Uniform Resource Indentifier,統一資源識別符號)
  • URL(Uniform Resource Locator,統一資源定位符)
  • URN(Uniform Resource Name,統一資源名稱),例如 urn:isbn:0-486-27557-4 。

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

請求和響應報文

1. 請求報文

2. 響應報文

二、HTTP 方法

客戶端傳送的 請求報文 第一行為請求行,包含了方法欄位。

GET:獲取資源

POST:傳輸實體主體

POST 主要目的不是獲取資源,而是傳輸儲存在內容實體中的資料。

GET 和 POST 的請求都能使用額外的引數,但是 GET 的引數是以查詢字串出現在 URL 中,而 POST 的引數儲存在內容實體。

GET /test/demo_form.asp?name1=value1&name2=value2 HTTP/1.1
POST /test/demo_form.asp HTTP/1.1
Host: w3schools.com
name1=value1&name2=value2

GET 的傳參方式相比於 POST 安全性較差,因為 GET 傳的引數在 URL 中是可見的,可能會洩露私密資訊。並且 GET 只支援 ASCII 字元,如果引數為中文則可能會出現亂碼,而 POST 支援標準字符集。

HEAD:獲取報文首部

和 GET 方法一樣,但是不返回報文實體主體部分。

主要用於確認 URL 的有效性以及資源更新的日期時間等。

PUT:上傳檔案

由於自身不帶驗證機制,任何人都可以上傳檔案,因此存在安全性問題,一般不使用該方法。

PUT /new.html HTTP/1.1
Host: example.com
Content-type: text/html
Content-length: 16

<p>New File</p>

PATCH:對資源進行部分修改

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

PATCH /file.txt HTTP/1.1
Host: www.example.com
Content-Type: application/example
If-Match: "e0023aa4e"
Content-Length: 100

[description of changes]

DELETE:刪除檔案

與 PUT 功能相反,並且同樣不帶驗證機制。

DELETE /file.html HTTP/1.1

OPTIONS:查詢支援的方法

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

會返回 Allow: GET, POST, HEAD, OPTIONS 這樣的內容。

CONNECT:要求用隧道協議連線代理

要求在於代理伺服器通訊時建立隧道,使用 SSL(Secure Sokets Layer,安全套接字)和 TLS(Transport Layer Security,傳輸層安全)協議把通訊內容加密後經網路隧道傳輸。

CONNECT www.example.com:443 HTTP/1.1

TRACE:追蹤路徑

伺服器會將通訊路徑返回給客戶端。

傳送請求時,在 Max-Forwards 首部欄位中填入數值,每經過一個伺服器就會減 1,當數值為 0 時就停止傳輸。

通常不會使用 TRACE,並且它容易受到 XST 攻擊(Cross-Site Tracing,跨站追蹤),因此更不會去使用它。

三、HTTP 狀態碼

伺服器返回的 響應報文 中第一行為狀態行,包含了狀態碼以及原因短語,用來告知客戶端請求的結果。

狀態碼 類別 原因短語
1XX Informational(資訊性狀態碼) 接收的請求正在處理
2XX Success(成功狀態碼) 請求正常處理完畢
3XX Redirection(重定向狀態碼) 需要進行附加操作以完成請求
4XX Client Error(客戶端錯誤狀態碼) 伺服器無法處理請求
5XX Server Error(伺服器錯誤狀態碼) 伺服器處理請求出錯

2XX 成功

  • 200 OK

  • 204 No Content :請求已經成功處理,但是返回的響應報文不包含實體的主體部分。一般在只需要從客戶端往伺服器傳送資訊,而不需要返回資料時使用。

  • 206 Partial Content :表示客戶端進行了範圍請求。響應報文包含由 Content-Range 指定範圍的實體內容。

3XX 重定向

  • 301 Moved Permanently :永久性重定向

  • 302 Found :臨時性重定向

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

  • 注:雖然 HTTP 協議規定 301、302 狀態下重定向時不允許把 POST 方法改成 GET 方法,但是大多數瀏覽器都會 在 301、302 和 303 狀態下的重定向把 POST 方法改成 GET 方法。

  • 304 Not Modified :如果請求報文首部包含一些條件,例如:If-Match,If-ModifiedSince,If-None-Match,If-Range,If-Unmodified-Since,但是不滿足條件,則伺服器會返回 304 狀態碼。

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

4XX 客戶端錯誤

  • 400 Bad Request :請求報文中存在語法錯誤。

  • 401 Unauthorized :該狀態碼錶示傳送的請求需要有認證資訊(BASIC 認證、DIGEST 認證)。如果之前已進行過一次請求,則表示使用者認證失敗。

  • 403 Forbidden :請求被拒絕,伺服器端沒有必要給出拒絕的詳細理由。

  • 404 Not Found

5XX 伺服器錯誤

  • 500 Internal Server Error :伺服器正在執行請求時發生錯誤。

  • 503 Service Unavilable :伺服器暫時處於超負載或正在進行停機維護,現在無法處理請求。

四、HTTP 首部

有 4 種類型的首部欄位:通用首部欄位、請求首部欄位、響應首部欄位和實體首部欄位。

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

通用首部欄位

首部欄位名 說明
Cache-Control 控制快取的行為
Connection 控制不再轉發給代理的首部欄位;管理持久連線
Date 建立報文的日期時間
Pragma 報文指令
Trailer 報文末端的首部一覽
Transfer-Encoding 指定報文主體的傳輸編碼方式
Upgrade 升級為其他協議
Via 代理伺服器的相關資訊
Warning 錯誤通知

請求首部欄位

首部欄位名 說明
Accept 使用者代理可處理的媒體型別
Accept-Charset 優先的字符集
Accept-Encoding 優先的內容編碼
Accept-Language 優先的語言(自然語言)
Authorization Web 認證資訊
Expect 期待伺服器的特定行為
From 使用者的電子郵箱地址
Host 請求資源所在伺服器
If-Match 比較實體標記(ETag)
If-Modified-Since 比較資源的更新時間
If-None-Match 比較實體標記(與 If-Match 相反)
If-Range 資源未更新時傳送實體 Byte 的範圍請求
If-Unmodified-Since 比較資源的更新時間(與 If-Modified-Since 相反)
Max-Forwards 最大傳輸逐跳數
Proxy-Authorization 代理伺服器要求客戶端的認證資訊
Range 實體的位元組範圍請求
Referer 對請求中 URI 的原始獲取方
TE 傳輸編碼的優先順序
User-Agent HTTP 客戶端程式的資訊

響應首部欄位

首部欄位名 說明
Accept-Ranges 是否接受位元組範圍請求
Age 推算資源建立經過時間
ETag 資源的匹配資訊
Location 令客戶端重定向至指定 URI
Proxy-Authenticate 代理伺服器對客戶端的認證資訊
Retry-After 對再次發起請求的時機要求
Server HTTP 伺服器的安裝資訊
Vary 代理伺服器快取的管理資訊
WWW-Authenticate 伺服器對客戶端的認證資訊

實體首部欄位

首部欄位名 說明
Allow 資源可支援的 HTTP 方法
Content-Encoding 實體主體適用的編碼方式
Content-Language 實體主體的自然語言
Content-Length 實體主體的大小(單位:位元組)
Content-Location 替代對應資源的 URI
Content-MD5 實體主體的報文摘要
Content-Range 實體主體的位置範圍
Content-Type 實體主體的媒體型別
Expires 實體主體過期的日期時間
Last-Modified 資源的最後修改日期時間

五、具體應用

Cookie

HTTP 協議是無狀態的,主要是為了讓 HTTP 協議儘可能簡單,使得它能夠處理大量事務。HTTP/1.1 引入 Cookie 來儲存狀態資訊。

Cookie 是伺服器傳送給客戶端的資料,該資料會被儲存在瀏覽器中,並且在下一次傳送請求時包含該資料。通過 Cookie 可以讓伺服器知道兩個請求是否來自於同一個客戶端,從而實現保持登入狀態等功能。

1. 建立過程

伺服器傳送的響應報文包含 Set-Cookie 欄位,客戶端得到響應報文後把 Cookie 內容儲存到瀏覽器中。

HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

[page content]

客戶端之後傳送請求時,會從瀏覽器中讀出 Cookie 值,在請求報文中包含 Cookie 欄位。

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

2. Set-Cookie

屬性 說明
NAME=VALUE 賦予 Cookie 的名稱和其值(必需項)
expires=DATE Cookie 的有效期(若不明確指定則預設為瀏覽器關閉前為止)
path=PATH 將伺服器上的檔案目錄作為 Cookie 的適用物件(若不指定則預設為文件所在的檔案目錄)
domain=域名 作為 Cookie 適用物件的域名(若不指定則預設為建立 Cookie 的伺服器的域名)
Secure 僅在 HTTPS 安全通訊時才會傳送 Cookie
HttpOnly 加以限制,使 Cookie 不能被 JavaScript 指令碼訪問

3. Session 和 Cookie 區別

Session 是伺服器用來跟蹤使用者的一種手段,每個 Session 都有一個唯一標識:Session ID。當伺服器建立了一個 Session 時,給客戶端傳送的響應報文就包含了 Set-Cookie 欄位,其中有一個名為 sid 的鍵值對,這個鍵值對就是 Session ID。客戶端收到後就把 Cookie 儲存在瀏覽器中,並且之後傳送的請求報文都包含 Session ID。HTTP 就是通過 Session 和 Cookie 這兩種方式一起合作來實現跟蹤使用者狀態的,Session 用於伺服器端,Cookie 用於客戶端。

4. 瀏覽器禁用 Cookie 的情況

會使用 URL 重寫技術,在 URL 後面加上 sid=xxx 。

5. 使用 Cookie 實現使用者名稱和密碼的自動填寫

網站指令碼會自動從儲存在瀏覽器中的 Cookie 讀取使用者名稱和密碼,從而實現自動填寫。

快取

1. 優點

  1. 降低伺服器的負擔;
  2. 提高響應速度(快取資源比伺服器上的資源離客戶端更近)。

2. 實現方法

  1. 讓代理伺服器進行快取;
  2. 讓客戶端瀏覽器進行快取。

3. Cache-Control 欄位

HTTP 通過 Cache-Control 首部欄位來控制快取。

Cache-Control: private, max-age=0, no-cache

4. no-cache 指令

該指令出現在請求報文的 Cache-Control 欄位中,表示快取伺服器需要先向原伺服器驗證快取資源是否過期;

該指令出現在響應報文的 Cache-Control 欄位中,表示快取伺服器在進行快取之前需要先驗證快取資源的有效性。

5. no-store 指令

該指令表示快取伺服器不能對請求或響應的任何一部分進行快取。

no-cache 不表示不快取,而是快取之前需要先進行驗證,no-store 才是不進行快取。

6. max-age 指令

該指令出現在請求報文的 Cache-Control 欄位中,如果快取資源的快取時間小於該指令指定的時間,那麼就能接受該快取。

該指令出現在響應報文的 Cache-Control 欄位中,表示快取資源在快取伺服器中儲存的時間。

Expires 欄位也可以用於告知快取伺服器該資源什麼時候會過期。在 HTTP/1.1 中,會優先處理 Cache-Control : max-age 指令;而在 HTTP/1.0 中,Cache-Control : max-age 指令會被忽略掉。

持久連線

當瀏覽器訪問一個包含多張圖片的 HTML 頁面時,除了請求訪問 HTML 頁面資源,還會請求圖片資源,如果每進行一次 HTTP 通訊就要斷開一次 TCP 連線,連線建立和斷開的開銷會很大。持久連線只需要建立一次 TCP 連線就能進行多次 HTTP 通訊。

持久連線需要使用 Connection 首部欄位進行管理。HTTP/1.1 開始 HTTP 預設是持久化連線的,如果要斷開 TCP 連線,需要由客戶端或者伺服器端提出斷開,使用 Connection : close;而在 HTTP/1.1 之前預設是非持久化連線的,如果要維持持續連線,需要使用 Connection : Keep-Alive。

管線化方式 可以同時傳送多個請求和響應,而不需要傳送一個請求然後等待響應之後再發下一個請求。

編碼

編碼(Encoding)主要是為了對實體進行壓縮。常用的編碼有:gzip、compress、deflate、identity,其中 identity 表示不執行壓縮的編碼格式。

分塊傳輸

分塊傳輸(Chunked Transfer Coding)可以把資料分割成多塊,讓瀏覽器逐步顯示頁面。

多部分物件集合

一份報文主體內可含有多種型別的實體同時傳送,每個部分之間用 boundary 欄位定義的分隔符進行分隔,每個部分都可以有首部欄位。

例如,上傳多個表單時可以使用如下方式:

Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="submit-name"

Larry
--AaB03x
Content-Disposition: form-data; name="files"; filename="file1.txt"
Content-Type: text/plain

... contents of file1.txt ...
--AaB03x--

範圍請求

如果網路出現中斷,伺服器只發送了一部分資料,範圍請求使得客戶端能夠只請求未傳送的那部分資料,從而避免伺服器端重新發送所有資料。

在請求報文首部中新增 Range 欄位,然後指定請求的範圍,例如 Range:bytes=5001-10000。請求成功的話伺服器傳送 206 Partial Content 狀態。

GET /z4d4kWk.jpg HTTP/1.1
Host: i.imgur.com
Range: bytes=0-1023
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/146515
Content-Length: 1024
...
(binary content)

內容協商

通過內容協商返回最合適的內容,例如根據瀏覽器的預設語言選擇返回中文介面還是英文介面。

涉及以下首部欄位:Accept、Accept-Charset、Accept-Encoding、Accept-Language、Content-Language。

虛擬主機

使用虛擬主機技術,使得一臺伺服器擁有多個域名,並且在邏輯上可以看成多個伺服器。

通訊資料轉發

1. 代理

代理伺服器接受客戶端的請求,並且轉發給其它伺服器。

代理伺服器一般是透明的,不會改變 URL。

使用代理的主要目的是:快取、網路訪問控制以及訪問日誌記錄。

2. 閘道器

與代理伺服器不同的是,閘道器伺服器會將 HTTP 轉化為其它協議進行通訊,從而請求其它非 HTTP 伺服器的服務。

3. 隧道

使用 SSL 等加密手段,為客戶端和伺服器之間建立一條安全的通訊線路。