要求在與代理伺服器通信時建立隧道,使用 SSL(Secure Sockets Layer,安全套接層)和 TLS(Transport Layer Security,傳輸層安全)協議把通信內容加密後經網路隧道傳輸。
TRACE
追蹤路徑
伺服器會將通信路徑返回給客戶端。
發送請求時,在 Max-Forwards 首部欄位中填入數值,每經過一個伺服器就會減 1,當數值為 0 時就停止傳輸。
通常不會使用 TRACE,並且它容易受到 XST 攻擊(Cross-Site Tracing,跨站追蹤),因此更不會去使用它。
HTTP Header
有 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/1.1 引入 Cookie 來保存狀態信息。
1. 用途
會話狀態管理 (如用戶登錄狀態、購物車、遊戲分數或其它需要記錄的信息)
個性化設置 (如用戶自定義設置、主題等)
瀏覽器行為跟蹤 (如跟蹤分析用戶行為等)
由於伺服器指定 Cookie 後,瀏覽器的每次請求都會攜帶 Cookie 數據,會帶來額外的性能開銷(尤其是在移動環境下)。
新的瀏覽器 API 已經允許開發者直接將數據存儲到本地 ,如使用 Web storage API (本地存儲和會話存儲)或 IndexedDB。
2. 創建過程
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
3. 分類
會話期 Cookie:瀏覽器關閉之後它會被自動刪除,也就是說它僅在會話期內有效。
持久性 Cookie:指定一個特定的過期時間(Expires)或有效期(Max-Age)之後就成為了持久性的 Cookie。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
4. 作用域
Domain 標識指定了哪些主機可以接受 Cookie。如果不指定,默認為當前文檔的主機(不包含子域名)。如果指定了 Domain,則一般包含子域名。例如,如果設置 Domain=http:// mozilla.org ,則 Cookie 也包含在子域名中(如 http:// developer.mozilla.org )。
Path 標識指定了主機下的哪些路徑可以接受 Cookie(該 URL 路徑必須存在於請求 URL 中)。以字元 %x2F ("/") 作為路徑分隔符,子路徑也會被匹配。例如,設置 Path=/docs,則以下地址都會匹配:
/docs
/docs/Web/
/docs/Web/HTTP
5. JavaScript
通過 Document.cookie
屬性可創建新的 Cookie,也可通過該屬性訪問非 HttpOnly 標記的 Cookie。
document.cookie = "yummy_cookie=choco";
document.cookie = "tasty_cookie=strawberry";
console.log(document.cookie);
6. Secure 和 HttpOnly
標記為 Secure 的 Cookie 只應通過被 HTTPS 協議加密過的請求發送給服務端 。但即便設置了 Secure 標記,敏感信息也不應該通過 Cookie 傳輸,因為 Cookie 有其固有的不安全性,Secure 標記也無法提供確實的安全保障。
標記為 HttpOnly 的 Cookie 不能被 JavaScript 腳本調用 。因為跨域腳本 (XSS) 攻擊常常使用 JavaScript 的 Document.cookie
API 竊取用戶的 Cookie 信息,因此使用 HttpOnly 標記可以在一定程度上避免 XSS 攻擊。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
7. Session和cookie選擇
除了可以將用戶信息通過 Cookie 存儲在用戶瀏覽器中,也可以利用 Session 存儲在伺服器端,存儲在伺服器端的信息更加安全。
Session 可以存儲在伺服器上的文件、資料庫或者內存中。也可以將 Session 存儲在 Redis 這種內存型資料庫中,效率會更高。
使用 Session 維護用戶登錄狀態的過程如下:
用戶進行登錄時,用戶提交包含用戶名和密碼的表單,放入 HTTP 請求報文中;
伺服器驗證該用戶名和密碼,如果正確則把用戶信息存儲到 Redis 中,它在 Redis 中的 Key 稱為 Session ID;
伺服器返回的響應報文的 Set-Cookie 首部欄位包含了這個 Session ID,客戶端收到響應報文之後將該 Cookie 值存入瀏覽器中;
客戶端之後對同一個伺服器進行請求時會包含該 Cookie 值,伺服器收到之後提取出 Session ID,從 Redis 中取出用戶信息,繼續之前的業務操作。
應該注意 Session ID 的安全性問題,不能讓它被惡意攻擊者輕易獲取,那麼就不能產生一個容易被猜到的 Session ID 值。此外,還需要經常重新生成 Session ID。在對安全性要求極高的場景下,例如轉賬等操作,除了使用 Session 管理用戶狀態之外,還需要對用戶進行重新驗證,比如重新輸入密碼,或者使用簡訊驗證碼等方式。
從存儲方式上比較
Cookie只能存儲字元串,如果要存儲非ASCII字元串還要對其編碼。
Session可以存儲任何類型的數據,可以把Session看成是一個容器
從隱私安全上比較
Cookie存儲在瀏覽器中,對客戶端是可見的。信息容易泄露出去。如果使用Cookie,最好將Cookie加密
Session存儲在伺服器上,對客戶端是透明的。不存在敏感信息泄露問題。
從有效期上比較
Cookie保存在硬碟中,只需要設置maxAge屬性為比較大的正整數,即使關閉瀏覽器,Cookie還是存在的
Session的保存在伺服器中,設置maxInactiveInterval屬性值來確定Session的有效期。並且Session依賴於名為JSESSIONID的Cookie ,該Cookie默認的maxAge屬性為-1。如果關閉了瀏覽器,該Session雖然沒有從伺服器中消亡,但也就失效了。
從對伺服器的負擔比較
Session是保存在伺服器的,每個用戶都會產生一個Session,如果是並發訪問的用戶非常多,是不能使用Session的,Session會消耗大量的內存。
Cookie是保存在客戶端的。不佔用伺服器的資源。像baidu、Sina這樣的大型網站,一般都是使用Cookie來進行會話跟蹤。
從瀏覽器的支持上比較
如果瀏覽器禁用了Cookie,那麼Cookie是無用的了!
如果瀏覽器禁用了Cookie,Session可以通過URL地址重寫 來進行會話跟蹤。
從跨域名上比較
Cookie可以設置domain屬性來實現跨域名
Session只在當前的域名內有效,不可誇域名
緩存
1. 優點
緩解伺服器壓力;
減低客戶端獲取資源的延遲(緩存資源比伺服器上的資源離客戶端更近)。
2. 實現方法
3. Cache-Control
HTTP/1.1 通過 Cache-Control 首部欄位來控制緩存。
(一)禁止進行緩存
no-store 指令規定不能對請求或響應的任何一部分進行緩存。
Cache-Control: no-store
(二)強制確認緩存
no-cache 指令規定緩存伺服器需要先向源伺服器驗證緩存資源的有效性,只有當緩存資源有效才將能使用該緩存對客戶端的請求進行響應。
Cache-Control: no-cache
(三)私有緩存和公共緩存
private 指令規定了將資源作為私有緩存,只能被單獨用戶所使用,一般存儲在用戶瀏覽器中。
Cache-Control: private
public 指令規定了將資源作為公共緩存,可以被多個用戶所使用,一般存儲在代理伺服器中。
Cache-Control: public
(四)緩存過期機制
max-age 指令出現在請求報文中,並且緩存資源的緩存時間小於該指令指定的時間,那麼就能接受該緩存。
max-age 指令出現在響應報文中,表示緩存資源在緩存伺服器中保存的時間。
Cache-Control: max-age=31536000
Expires 欄位也可以用於告知緩存伺服器該資源什麼時候會過期。在 HTTP/1.1 中,會優先處理 Cache-Control : max-age 指令;而在 HTTP/1.0 中,Cache-Control : max-age 指令會被忽略掉。
Expires: Wed, 04 Jul 2012 08:26:05 GMT
4. 緩存驗證
需要先了解 ETag 首部欄位的含義,它是資源的唯一表示。URL 不能唯一表示資源,例如 http://www.google.com/
有中文和英文兩個資源,只有 ETag 才能對這兩個資源進行唯一表示。
ETag: "82e22293907ce725faf67773957acd12"
可以將緩存資源的 ETag 值放入 If-None-Match 首部,伺服器收到該請求後,判斷緩存資源的 ETag 值和資源的最新 ETag 值是否一致,如果一致則表示緩存資源有效,返回 304 Not Modified。
If-None-Match: "82e22293907ce725faf67773957acd12"
Last-Modified 首部欄位也可以用於緩存驗證,它包含在源伺服器發送的響應報文中,指示源伺服器對資源的最後修改時間。但是它是一種弱校驗器,因為只能精確到一秒,所以它通常作為 ETag 的備用方案 。如果響應首部欄位里含有這個信息,客戶端可以在後續的請求中帶上 If-Modified-Since 來驗證緩存。伺服器只在所請求的資源在給定的日期時間之後對內容進行過修改的情況下才會將資源返回,狀態碼為 200 OK。如果請求的資源從那時起未經修改,那麼返回一個不帶有消息主體的 304 Not Modified 響應,
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT
連接管理
1. 短連接與長連接
HTTP/1.1 開始默認是長連接的,如果要斷開連接,需要由客戶端或者伺服器端提出斷開,使用 Connection : close;
HTTP/1.1 之前默認是短連接的,如果需要長連接,則使用 Connection : Keep-Alive。
2. 流水線
默認情況下,HTTP 請求是按順序發出的,下一個請求只有在當前請求收到應答過後才會被發出。由於會受到網路延遲和帶寬的限制,在下一個請求被發送到伺服器之前,可能需要等待很長時間。
流水線是在同一條長連接上發出連續的請求,而不用等待響應返回,這樣可以避免連接延遲。
內容協商
通過內容協商返回最合適的內容,例如根據瀏覽器的默認語言選擇返回中文界面還是英文界面。
1. 類型
1.1 服務端驅動型
客戶端設置特定的 HTTP 首部欄位,例如 Accept、Accept-Charset、Accept-Encoding、Accept-Language,伺服器根據這些欄位返回特定的資源。
它存在以下問題:
伺服器很難知道客戶端瀏覽器的全部信息;
客戶端提供的信息相當冗長(HTTP/2 協議的首部壓縮機制緩解了這個問題),並且存在隱私風險(HTTP 指紋識別技術);
給定的資源需要返回不同的展現形式,共享緩存的效率會降低,而伺服器端的實現會越來越複雜。
1.2 代理驅動型
伺服器返回 300 Multiple Choices 或者 406 Not Acceptable,客戶端從中選出最合適的那個資源。
2. Vary
Vary: Accept-Language
在使用內容協商的情況下,只有當緩存伺服器中的緩存滿足內容協商條件時,才能使用該緩存,否則應該向源伺服器請求該資源。
例如,一個客戶端發送了一個包含 Accept-Language 首部欄位的請求之後,源伺服器返回的響應包含 Vary: Accept-Language
內容,緩存伺服器對這個響應進行緩存之後,在客戶端下一次訪問同一個 URL 資源,並且 Accept-Language 與緩存中的對應的值相同時才會返回該緩存。
內容編碼
內容編碼將實體主體進行壓縮,從而減少傳輸的數據量。常用的內容編碼有:gzip、compress、deflate、identity。
瀏覽器發送 Accept-Encoding 首部,其中包含有它所支持的壓縮演算法,以及各自的優先順序,伺服器則從中選擇一種,使用該演算法對響應的消息主體進行壓縮,並且發送 Content-Encoding 首部來告知瀏覽器它選擇了哪一種演算法。由於該內容協商過程是基於編碼類型來選擇資源的展現形式的,在響應中,Vary 首部中至少要包含 Content-Encoding,這樣的話,緩存伺服器就可以對資源的不同展現形式進行緩存。
範圍請求
如果網路出現中斷,伺服器只發送了一部分數據,範圍請求可以使得客戶端只請求伺服器未發送的那部分數據,從而避免伺服器重新發送所有數據。
1. Range
在請求報文中添加 Range 首部欄位指定請求的範圍。
GET /z4d4kWk.jpg HTTP/1.1
Host: i.imgur.com
Range: bytes=0-1023
請求成功的話伺服器返回的響應包含 206 Partial Content 狀態碼。
2. Accept-Ranges
響應首部欄位 Accept-Ranges 用於告知客戶端是否能處理範圍請求,可以處理使用 bytes,否則使用 none。
Accept-Ranges: bytes
3. 響應狀態碼
在請求成功的情況下,伺服器會返回 206 Partial Content 狀態碼。
在請求的範圍越界的情況下,伺服器會返回 416 Requested Range Not Satisfiable 狀態碼。
在不支持範圍請求的情況下,伺服器會返回 200 OK 狀態碼。
分塊傳輸編碼
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--
虛擬主機
HTTP/1.1 使用虛擬主機技術,使得一台伺服器擁有多個域名,並且在邏輯上可以看成多個伺服器。
通信數據轉發
1. 代理
代理伺服器接受客戶端的請求,並且轉發給其它伺服器。
使用代理的主要目的是:
代理伺服器分為正向代理和反向代理兩種:
用戶察覺得到正向代理的存在。
而反向代理一般位於內部網路中,用戶察覺不到。
2. 網關
與代理伺服器不同的是,網關伺服器會將 HTTP 轉化為其它協議進行通信,從而請求其它非 HTTP 伺服器的服務。
3. 隧道
使用 SSL 等加密手段,為客戶端和伺服器之間建立一條安全的通信線路。
--------------------正文完-----------------------
關注我
我是蠻三刀把刀,目前為後台開發工程師。主要關注後台開發,網路安全,Python爬蟲等技術。
來微信和我聊聊:yangzd1102
Github:https:// github.com/qqxx6661
原創博客主要內容
筆試面試複習知識點手冊
Leetcode演算法題解析(前150題)
劍指offer演算法題解析
Python爬蟲相關技術分析和實戰
後台開發相關技術分析和實戰
同步更新以下博客
1. Csdn
http:// blog.csdn.net/qqxx6661
擁有專欄:Leetcode題解(Java/Python)、Python爬蟲開發、面試助攻手冊
2. 知乎
https://www. zhihu.com/people/yang-z hen-dong-1/
擁有專欄:碼農面試助攻手冊
3. 掘金
https:// juejin.im/user/5b48015c e51d45191462ba55
4. 簡書
https://www. jianshu.com/u/b5f225ca2 376
個人公眾號:Rude3Knife
如果文章對你有幫助,不妨收藏起來並轉發給您的朋友們~
推薦閱讀: