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. 優點
- 降低伺服器的負擔;
- 提高響應速度(快取資源比伺服器上的資源離客戶端更近)。
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 等加密手段,為客戶端和伺服器之間建立一條安全的通訊線路。