Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
者:滌生_Woo
一張圖帶你看完本篇文章
計(jì)算機(jī)網(wǎng)絡(luò)體系結(jié)構(gòu)分層
利用 TCP/IP 協(xié)議族進(jìn)行網(wǎng)絡(luò)通信時(shí),會(huì)通過分層順序與對(duì)方進(jìn)行通信。發(fā)送端從應(yīng)用層往下走,接收端則從鏈路層往上走。如下:
TCP/IP 通信傳輸流
如下圖所示:
HTTP 請(qǐng)求
在網(wǎng)絡(luò)體系結(jié)構(gòu)中,包含了眾多的網(wǎng)絡(luò)協(xié)議,這篇文章主要圍繞 HTTP 協(xié)議(HTTP/1.1版本)展開。
HTTP協(xié)議(HyperText Transfer Protocol,超文本傳輸協(xié)議)是用于從WWW服務(wù)器傳輸超文本到本地瀏覽器的傳輸協(xié)議。它可以使瀏覽器更加高效,使網(wǎng)絡(luò)傳輸減少。它不僅保證計(jì)算機(jī)正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內(nèi)容首先顯示(如文本先于圖形)等。 HTTP是客戶端瀏覽器或其他程序與Web服務(wù)器之間的應(yīng)用層通信協(xié)議。在Internet上的Web服務(wù)器上存放的都是超文本信息,客戶機(jī)需要通過HTTP協(xié)議傳輸所要訪問的超文本信息。HTTP包含命令和傳輸信息,不僅可用于Web訪問,也可以用于其他因特網(wǎng)/內(nèi)聯(lián)網(wǎng)應(yīng)用系統(tǒng)之間的通信,從而實(shí)現(xiàn)各類應(yīng)用資源超媒體訪問的集成。 我們?cè)跒g覽器的地址欄里輸入的網(wǎng)站地址叫做URL (Uniform Resource Locator,統(tǒng)一資源定位符)。就像每家每戶都有一個(gè)門牌地址一樣,每個(gè)網(wǎng)頁(yè)也都有一個(gè)Internet地址。當(dāng)你在瀏覽器的地址框中輸入一個(gè)URL或是單擊一個(gè)超級(jí)鏈接時(shí),URL就確定了要瀏覽的地址。瀏覽器通過超文本傳輸協(xié)議(HTTP),將Web服務(wù)器上站點(diǎn)的網(wǎng)頁(yè)代碼提取出來,并翻譯成漂亮的網(wǎng)頁(yè)。
HTTP請(qǐng)求響應(yīng)模型
HTTP通信機(jī)制是在一次完整的 HTTP 通信過程中,客戶端與服務(wù)器之間將完成下列7個(gè)步驟:
應(yīng)用 HTTP 協(xié)議時(shí),必定是一端擔(dān)任客戶端角色,另一端擔(dān)任服務(wù)器端角色。僅從一條通信線路來說,服務(wù)器端和客服端的角色是確定的。HTTP 協(xié)議規(guī)定,請(qǐng)求從客戶端發(fā)出,最后服務(wù)器端響應(yīng)該請(qǐng)求并返回。換句話說,肯定是先從客戶端開始建立通信的,服務(wù)器端在沒有接收到請(qǐng)求之前不會(huì)發(fā)送響應(yīng)。
HTTP 是一種無(wú)狀態(tài)協(xié)議。協(xié)議自身不對(duì)請(qǐng)求和響應(yīng)之間的通信狀態(tài)進(jìn)行保存。也就是說在 HTTP 這個(gè)級(jí)別,協(xié)議對(duì)于發(fā)送過的請(qǐng)求或響應(yīng)都不做持久化處理。這是為了更快地處理大量事務(wù),確保協(xié)議的可伸縮性,而特意把 HTTP 協(xié)議設(shè)計(jì)成如此簡(jiǎn)單的。 可是隨著 Web 的不斷發(fā)展,我們的很多業(yè)務(wù)都需要對(duì)通信狀態(tài)進(jìn)行保存。于是我們引入了 Cookie 技術(shù)。有了 Cookie 再用 HTTP 協(xié)議通信,就可以管理狀態(tài)了。
Cookie 技術(shù)通過在請(qǐng)求和響應(yīng)報(bào)文中寫入 Cookie 信息來控制客戶端的狀態(tài)。Cookie 會(huì)根據(jù)從服務(wù)器端發(fā)送的響應(yīng)報(bào)文內(nèi)的一個(gè)叫做 Set-Cookie 的首部字段信息,通知客戶端保存Cookie。當(dāng)下次客戶端再往該服務(wù)器發(fā)送請(qǐng)求時(shí),客戶端會(huì)自動(dòng)在請(qǐng)求報(bào)文中加入 Cookie 值后發(fā)送出去。服務(wù)器端發(fā)現(xiàn)客戶端發(fā)送過來的 Cookie 后,會(huì)去檢查究竟是從哪一個(gè)客戶端發(fā)來的連接請(qǐng)求,然后對(duì)比服務(wù)器上的記錄,最后得到之前的狀態(tài)信息。
Cookie 的流程
HTTP 協(xié)議使用 URI 定位互聯(lián)網(wǎng)上的資源。正是因?yàn)?URI 的特定功能,在互聯(lián)網(wǎng)上任意位置的資源都能訪問到。
HTTP 方法
HTTP 協(xié)議的初始版本中,每進(jìn)行一個(gè) HTTP 通信都要斷開一次 TCP 連接。比如使用瀏覽器瀏覽一個(gè)包含多張圖片的 HTML 頁(yè)面時(shí),在發(fā)送請(qǐng)求訪問 HTML 頁(yè)面資源的同時(shí),也會(huì)請(qǐng)求該 HTML 頁(yè)面里包含的其他資源。因此,每次的請(qǐng)求都會(huì)造成無(wú)畏的 TCP 連接建立和斷開,增加通信量的開銷。 為了解決上述 TCP 連接的問題,HTTP/1.1 和部分 HTTP/1.0 想出了持久連接的方法。其特點(diǎn)是,只要任意一端沒有明確提出斷開連接,則保持 TCP 連接狀態(tài)。旨在建立一次 TCP 連接后進(jìn)行多次請(qǐng)求和響應(yīng)的交互。在 HTTP/1.1 中,所有的連接默認(rèn)都是持久連接。
持久連接使得多數(shù)請(qǐng)求以管線化方式發(fā)送成為可能。以前發(fā)送請(qǐng)求后需等待并接收到響應(yīng),才能發(fā)送下一個(gè)請(qǐng)求。管線化技術(shù)出現(xiàn)后,不用等待亦可發(fā)送下一個(gè)請(qǐng)求。這樣就能做到同時(shí)并行發(fā)送多個(gè)請(qǐng)求,而不需要一個(gè)接一個(gè)地等待響應(yīng)了。 比如,當(dāng)請(qǐng)求一個(gè)包含多張圖片的 HTML 頁(yè)面時(shí),與挨個(gè)連接相比,用持久連接可以讓請(qǐng)求更快結(jié)束。而管線化技術(shù)要比持久連接速度更快。請(qǐng)求數(shù)越多,時(shí)間差就越明顯。
用于 HTTP 協(xié)議交互的信息被稱為 HTTP 報(bào)文。請(qǐng)求端(客戶端)的 HTTP 報(bào)文叫做請(qǐng)求報(bào)文;響應(yīng)端(服務(wù)器端)的叫做響應(yīng)報(bào)文。HTTP 報(bào)文本身是由多行(用 CR+LF 作換行符)數(shù)據(jù)構(gòu)成的字符串文本。
HTTP 報(bào)文大致可分為報(bào)文首部和報(bào)文主體兩部分。兩者由最初出現(xiàn)的空行(CR+LF)來劃分。通常,并不一定有報(bào)文主體。如下:
HTTP 報(bào)文結(jié)構(gòu)
請(qǐng)求報(bào)文結(jié)構(gòu)
請(qǐng)求報(bào)文的首部?jī)?nèi)容由以下數(shù)據(jù)組成:
請(qǐng)求報(bào)文的示例,如下:
請(qǐng)求報(bào)文示例
響應(yīng)報(bào)文結(jié)構(gòu)
響應(yīng)報(bào)文的首部?jī)?nèi)容由以下數(shù)據(jù)組成:
響應(yīng)報(bào)文的示例,如下:
響應(yīng)報(bào)文示例
舉個(gè)栗子,下面是一個(gè) HTTP 請(qǐng)求的報(bào)文:
GET /index.htm HTTP/1.1
Host: sample.com
其中,下面的這行就是請(qǐng)求行,
GET /index.htm HTTP/1.1
綜合來看,大意是請(qǐng)求訪問某臺(tái) HTTP 服務(wù)器上的 /index.htm 頁(yè)面資源。
同樣舉個(gè)栗子,下面是一個(gè) HTTP 響應(yīng)的報(bào)文:
HTTP/1.1 200 OK
Date: Mon, 10 Jul 2017 15:50:06 GMT
Content-Length: 256
Content-Type: text/html
<html>
...
其中,下面的這行就是狀態(tài)行,
HTTP/1.1 200 OK
先來回顧一下首部字段在報(bào)文的位置,HTTP 報(bào)文包含報(bào)文首部和報(bào)文主體,報(bào)文首部包含請(qǐng)求行(或狀態(tài)行)和首部字段。 在報(bào)文眾多的字段當(dāng)中,HTTP 首部字段包含的信息最為豐富。首部字段同時(shí)存在于請(qǐng)求和響應(yīng)報(bào)文內(nèi),并涵蓋 HTTP 報(bào)文相關(guān)的內(nèi)容信息。使用首部字段是為了給客服端和服務(wù)器端提供報(bào)文主體大小、所使用的語(yǔ)言、認(rèn)證信息等內(nèi)容。
首部字段名 冒號(hào) 字段值 Content-Type : text/html Keep-Alive : timeout=30, max=120
首部字段根據(jù)實(shí)際用途被分為以下4種類型:
類型 描述 通用首部字段 請(qǐng)求報(bào)文和響應(yīng)報(bào)文兩方都會(huì)使用的首部 請(qǐng)求首部字段 從客戶端向服務(wù)器端發(fā)送請(qǐng)求報(bào)文時(shí)使用的首部。補(bǔ)充了請(qǐng)求的附加內(nèi)容、客戶端信息、響應(yīng)內(nèi)容相關(guān)優(yōu)先級(jí)等信息 響應(yīng)首部字段 從服務(wù)器端向客戶端返回響應(yīng)報(bào)文時(shí)使用的首部。補(bǔ)充了響應(yīng)的附加內(nèi)容,也會(huì)要求客戶端附加額外的內(nèi)容信息。 實(shí)體首部字段 針對(duì)請(qǐng)求報(bào)文和響應(yīng)報(bào)文的實(shí)體部分使用的首部。補(bǔ)充了資源內(nèi)容更新時(shí)間等與實(shí)體有關(guān)的的信息。
首部字段名 說明 Cache-Control 控制緩存的行為 Connection 逐挑首部、連接的管理 Date 創(chuàng)建報(bào)文的日期時(shí)間 Pragma 報(bào)文指令 Trailer 報(bào)文末端的首部一覽 Transfer-Encoding 指定報(bào)文主體的傳輸編碼方式 Upgrade 升級(jí)為其他協(xié)議 Via 代理服務(wù)器的相關(guān)信息 Warning 錯(cuò)誤通知
通過指定首部字段 Cache-Control 的指令,就能操作緩存的工作機(jī)制。
可用的指令按請(qǐng)求和響應(yīng)分類如下: 緩存請(qǐng)求指令
指令 參數(shù) 說明 no-cache 無(wú) 強(qiáng)制向服務(wù)器再次驗(yàn)證 no-store 無(wú) 不緩存請(qǐng)求或響應(yīng)的任何內(nèi)容 max-age=[秒] 必需 響應(yīng)的最大Age值 max-stale(=[秒]) 可省略 接收已過期的響應(yīng) min-fresh=[秒] 必需 期望在指定時(shí)間內(nèi)的響應(yīng)仍有效 no-transform 無(wú) 代理不可更改媒體類型 only-if-cached 無(wú) 從緩存獲取資源 cache-extension - 新指令標(biāo)記(token)
緩存響應(yīng)指令
指令 參數(shù) 說明 public 無(wú) 可向任意方提供響應(yīng)的緩存 private 可省略 僅向特定用戶返回響應(yīng) no-cache 可省略 緩存前必須先確認(rèn)其有效性 no-store 無(wú) 不緩存請(qǐng)求或響應(yīng)的任何內(nèi)容 no-transform 無(wú) 代理不可更改媒體類型 must-revalidate 無(wú) 可緩存但必須再向源服務(wù)器進(jìn)行確認(rèn) proxy-revalidate 無(wú) 要求中間緩存服務(wù)器對(duì)緩存的響應(yīng)有效性再進(jìn)行確認(rèn) max-age=[秒] 必需 響應(yīng)的最大Age值 s-maxage=[秒] 必需 公共緩存服務(wù)器響應(yīng)的最大Age值 cache-extension - 新指令標(biāo)記(token)
public 指令 Cache-Control: public 當(dāng)指定使用 public 指令時(shí),則明確表明其他用戶也可利用緩存。
private 指令 Cache-Control: private 當(dāng)指定 private 指令后,響應(yīng)只以特定的用戶作為對(duì)象,這與 public 指令的行為相反。緩存服務(wù)器會(huì)對(duì)該特定用戶提供資源緩存的服務(wù),對(duì)于其他用戶發(fā)送過來的請(qǐng)求,代理服務(wù)器則不會(huì)返回緩存。
no-cache 指令 Cache-Control: no-cache
Cache-Control: no-cache=Location 由服務(wù)器返回的響應(yīng)中,若報(bào)文首部字段 Cache-Control 中對(duì) no-cache 字段名具體指定參數(shù)值,那么客戶端在接收到這個(gè)被指定參數(shù)值的首部字段對(duì)應(yīng)的響應(yīng)報(bào)文后,就不能使用緩存。換言之,無(wú)參數(shù)值的首部字段可以使用緩存。只能在響應(yīng)指令中指定該參數(shù)。
no-store 指令 Cache-Control: no-store 當(dāng)使用 no-store 指令時(shí),暗示請(qǐng)求(和對(duì)應(yīng)的響應(yīng))或響應(yīng)中包含機(jī)密信息。因此,該指令規(guī)定緩存不能在本地存儲(chǔ)請(qǐng)求或響應(yīng)的任一部分。 注意:no-cache 指令代表不緩存過期的指令,緩存會(huì)向源服務(wù)器進(jìn)行有效期確認(rèn)后處理資源;no-store 指令才是真正的不進(jìn)行緩存。
s-maxage 指令 Cache-Control: s-maxage=604800(單位:秒)
max-age 指令 Cache-Control: max-age=604800(單位:秒)
min-fresh 指令 Cache-Control: min-fresh=60(單位:秒) min-fresh 指令要求緩存服務(wù)器返回至少還未過指定時(shí)間的緩存資源。
max-stale 指令 Cache-Control: max-stale=3600(單位:秒)
only-if-cached 指令 Cache-Control: only-if-cached 表示客戶端僅在緩存服務(wù)器本地緩存目標(biāo)資源的情況下才會(huì)要求其返回。換言之,該指令要求緩存服務(wù)器不重新加載響應(yīng),也不會(huì)再次確認(rèn)資源的有效性。
must-revalidate 指令 Cache-Control: must-revalidate 使用 must-revalidate 指令,代理會(huì)向源服務(wù)器再次驗(yàn)證即將返回的響應(yīng)緩存目前是否仍有效。另外,使用 must-revalidate 指令會(huì)忽略請(qǐng)求的 max-stale 指令。
proxy-revalidate 指令 Cache-Control: proxy-revalidate proxy-revalidate 指令要求所有的緩存服務(wù)器在接收到客戶端帶有該指令的請(qǐng)求返回響應(yīng)之前,必須再次驗(yàn)證緩存的有效性。
no-transform 指令 Cache-Control: no-transform 使用 no-transform 指令規(guī)定無(wú)論是在請(qǐng)求還是響應(yīng)中,緩存都不能改變實(shí)體主體的媒體類型。這樣做可防止緩存或代理壓縮圖片等類似操作。
Cache-Control: private, community="UCI" 通過 cache-extension 標(biāo)記(token),可以擴(kuò)展 Cache-Control 首部字段內(nèi)的指令。上述 community 指令即擴(kuò)展的指令,如果緩存服務(wù)器不能理解這個(gè)新指令,就會(huì)直接忽略掉。
Connection 首部字段具備以下兩個(gè)作用:
控制不再轉(zhuǎn)發(fā)的首部字段 Connection: Upgrade 在客戶端發(fā)送請(qǐng)求和服務(wù)器返回響應(yīng)中,使用 Connection 首部字段,可控制不再轉(zhuǎn)發(fā)給代理的首部字段,即刪除后再轉(zhuǎn)發(fā)(即Hop-by-hop首部)。
管理持久連接 Connection: close HTTP/1.1 版本的默認(rèn)連接都是持久連接。當(dāng)服務(wù)器端想明確斷開連接時(shí),則指定 Connection 首部字段的值為 close。 Connection: Keep-Alive HTTP/1.1 之前的 HTTP 版本的默認(rèn)連接都是非持久連接。為此,如果想在舊版本的 HTTP 協(xié)議上維持持續(xù)連接,則需要指定 Connection 首部字段的值為 Keep-Alive。
表明創(chuàng)建 HTTP 報(bào)文的日期和時(shí)間。 Date: Mon, 10 Jul 2017 15:50:06 GMT HTTP/1.1 協(xié)議使用在 RFC1123 中規(guī)定的日期時(shí)間的格式。
Pragma 首部字段是 HTTP/1.1 版本之前的歷史遺留字段,僅作為與 HTTP/1.0 的向后兼容而定義。 Pragma: no-cache
Cache-Control: no-cache
Pragma: no-cache
Trailer: Expires 首部字段 Trailer 會(huì)事先說明在報(bào)文主體后記錄了哪些首部字段。可應(yīng)用在 HTTP/1.1 版本分塊傳輸編碼時(shí)。
Transfer-Encoding: chunked
Upgrade: TSL/1.0 用于檢測(cè) HTTP 協(xié)議及其他協(xié)議是否可使用更高的版本進(jìn)行通信,其參數(shù)值可以用來指定一個(gè)完全不同的通信協(xié)議。
Via: 1.1 a1.sample.com(Squid/2.7)
該首部字段通常會(huì)告知用戶一些與緩存相關(guān)的問題的警告。 Warning 首部字段的格式如下: Warning:[警告碼][警告的主機(jī):端口號(hào)] "[警告內(nèi)容]"([日期時(shí)間]) 最后的日期時(shí)間可省略。 HTTP/1.1 中定義了7種警告,警告碼對(duì)應(yīng)的警告內(nèi)容僅推薦參考,另外,警告碼具備擴(kuò)展性,今后有可能追加新的警告碼。
警告碼 警告內(nèi)容 說明 110 Response is stale(響應(yīng)已過期) 代理返回已過期的資源 111 Revalidation failed(再驗(yàn)證失敗) 代理再驗(yàn)證資源有效性時(shí)失敗(服務(wù)器無(wú)法到達(dá)等原因) 112 Disconnection operation(斷開連接操作) 代理與互聯(lián)網(wǎng)連接被故意切斷 113 Heuristic expiration(試探性過期) 響應(yīng)的試用期超過24小時(shí)(有效緩存的設(shè)定時(shí)間大于24小時(shí)的情況下) 199 Miscellaneous warning(雜項(xiàng)警告) 任意的警告內(nèi)容 214 Transformation applied(使用了轉(zhuǎn)換) 代理對(duì)內(nèi)容編碼或媒體類型等執(zhí)行了某些處理時(shí) 299 Miscellaneous persistent warning(持久雜項(xiàng)警告) 任意的警告內(nèi)容
首部字段名 說明 Accept 用戶代理可處理的媒體類型 Accept-Charset 優(yōu)先的字符集 Accept-Encoding 優(yōu)先的內(nèi)容編碼 Accept-Language 優(yōu)先的語(yǔ)言(自然語(yǔ)言) Authorization Web認(rèn)證信息 Expect 期待服務(wù)器的特定行為 From 用戶的電子郵箱地址 Host 請(qǐng)求資源所在服務(wù)器 If-Match 比較實(shí)體標(biāo)記(ETag) If-Modified-Since 比較資源的更新時(shí)間 If-None-Match 比較實(shí)體標(biāo)記(與 If-Macth 相反) If-Range 資源未更新時(shí)發(fā)送實(shí)體 Byte 的范圍請(qǐng)求 If-Unmodified-Since 比較資源的更新時(shí)間(與 If-Modified-Since 相反) Max-Forwards 最大傳輸逐跳數(shù) Proxy-Authorization 代理服務(wù)器要求客戶端的認(rèn)證信息 Range 實(shí)體的字節(jié)范圍請(qǐng)求 Referer 對(duì)請(qǐng)求中 URI 的原始獲取方 TE 傳輸編碼的優(yōu)先級(jí) User-Agent HTTP 客戶端程序的信息
Accept: text/html, application/xhtml+xml, application/xml; q=0.5
Accept-Charset: iso-8859-5, unicode-1-1; q=0.8 Accept-Charset 首部字段可用來通知服務(wù)器用戶代理支持的字符集及字符集的相對(duì)優(yōu)先順序。另外,可一次性指定多種字符集。同樣使用 q=[數(shù)值] 來表示相對(duì)優(yōu)先級(jí)。
Accept-Encoding: gzip, deflate Accept-Encoding 首部字段用來告知服務(wù)器用戶代理支持的內(nèi)容編碼及內(nèi)容編碼的優(yōu)先順序,并可一次性指定多種內(nèi)容編碼。同樣使用 q=[數(shù)值] 來表示相對(duì)優(yōu)先級(jí)。也可使用星號(hào)(*)作為通配符,指定任意的編碼格式。
Accept-Lanuage: zh-cn,zh;q=0.7,en=us,en;q=0.3 告知服務(wù)器用戶代理能夠處理的自然語(yǔ)言集(指中文或英文等),以及自然語(yǔ)言集的相對(duì)優(yōu)先級(jí),可一次性指定多種自然語(yǔ)言集。同樣使用 q=[數(shù)值] 來表示相對(duì)優(yōu)先級(jí)。
Authorization: Basic ldfKDHKfkDdasSAEdasd==告知服務(wù)器用戶代理的認(rèn)證信息(證書值)。通常,想要通過服務(wù)器認(rèn)證的用戶代理會(huì)在接收到返回的 401 狀態(tài)碼響應(yīng)后,把首部字段 Authorization 加入請(qǐng)求中。共用緩存在接收到含有 Authorization 首部字段的請(qǐng)求時(shí)的操作處理會(huì)略有差異。
Expect: 100-continue 告知服務(wù)器客戶端期望出現(xiàn)的某種特定行為。
From: Deeson_Woo@163.com 告知服務(wù)器使用用戶代理的電子郵件地址。
Host: www.jianshu.com
形如 If-xxx 這種樣式的請(qǐng)求首部字段,都可稱為條件請(qǐng)求。服務(wù)器接收到附帶條件的請(qǐng)求后,只有判斷指定條件為真時(shí),才會(huì)執(zhí)行請(qǐng)求。
If-Match: "123456"
If-Modified-Since: Mon, 10 Jul 2017 15:50:06 GMT
If-None-Match: "123456" 首部字段 If-None-Match 屬于附帶條件之一。它和首部字段 If-Match 作用相反。用于指定 If-None-Match 字段值的實(shí)體標(biāo)記(ETag)值與請(qǐng)求資源的 ETag 不一致時(shí),它就告知服務(wù)器處理該請(qǐng)求。
If-Range: "123456"
If-Unmodified-Since: Mon, 10 Jul 2017 15:50:06 GMT 首部字段 If-Unmodified-Since 和首部字段 If-Modified-Since 的作用相反。它的作用的是告知服務(wù)器,指定的請(qǐng)求資源只有在字段值內(nèi)指定的日期時(shí)間之后,未發(fā)生更新的情況下,才能處理請(qǐng)求。如果在指定日期時(shí)間后發(fā)生了更新,則以狀態(tài)碼 412 Precondition Failed 作為響應(yīng)返回。
Max-Forwards: 10 通過 TRACE 方法或 OPTIONS 方法,發(fā)送包含首部字段 Max-Forwards 的請(qǐng)求時(shí),該字段以十進(jìn)制整數(shù)形式指定可經(jīng)過的服務(wù)器最大數(shù)目。服務(wù)器在往下一個(gè)服務(wù)器轉(zhuǎn)發(fā)請(qǐng)求之前,Max-Forwards 的值減 1 后重新賦值。當(dāng)服務(wù)器接收到 Max-Forwards 值為 0 的請(qǐng)求時(shí),則不再進(jìn)行轉(zhuǎn)發(fā),而是直接返回響應(yīng)。
Proxy-Authorization: Basic dGlwOjkpNLAGfFY5
Range: bytes=5001-10000
Referer: http://www.sample.com/index.html 首部字段 Referer 會(huì)告知服務(wù)器請(qǐng)求的原始資源的 URI。
TE: gzip, deflate; q=0.5
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101
首部字段名 說明 Accept-Ranges 是否接受字節(jié)范圍請(qǐng)求 Age 推算資源創(chuàng)建經(jīng)過時(shí)間 ETag 資源的匹配信息 Location 令客戶端重定向至指定 URI Proxy-Authenticate 代理服務(wù)器對(duì)客戶端的認(rèn)證信息 Retry-After 對(duì)再次發(fā)起請(qǐng)求的時(shí)機(jī)要求 Server HTTP 服務(wù)器的安裝信息 Vary 代理服務(wù)器緩存的管理信息 WWW-Authenticate 服務(wù)器對(duì)客戶端的認(rèn)證信息
Accept-Ranges: bytes
Age: 1200
ETag: "usagi-1234"
Location: http://www.sample.com/sample.html
Proxy-Authenticate: Basic realm="Usagidesign Auth"
Retry-After: 180
Server: Apache/2.2.6 (Unix) PHP/5.2.5 首部字段 Server 告知客戶端當(dāng)前服務(wù)器上安裝的 HTTP 服務(wù)器應(yīng)用程序的信息。不單單會(huì)標(biāo)出服務(wù)器上的軟件應(yīng)用名稱,還有可能包括版本號(hào)和安裝時(shí)啟用的可選項(xiàng)。
Vary: Accept-Language
WWW-Authenticate: Basic realm="Usagidesign Auth" 首部字段 WWW-Authenticate 用于 HTTP 訪問認(rèn)證。它會(huì)告知客戶端適用于訪問請(qǐng)求 URI 所指定資源的認(rèn)證方案(Basic 或是 Digest)和帶參數(shù)提示的質(zhì)詢(challenge)。
首部字段名 說明 Allow 資源可支持的 HTTP 方法 Content-Encoding 實(shí)體主體適用的編碼方式 Content-Language 實(shí)體主體的自然語(yǔ)言 Content-Length 實(shí)體主體的大小(單位:字節(jié)) Content-Location 替代對(duì)應(yīng)資源的 URI Content-MD5 實(shí)體主體的報(bào)文摘要 Content-Range 實(shí)體主體的位置范圍 Content-Type 實(shí)體主體的媒體類型 Expires 實(shí)體主體過期的日期時(shí)間 Last-Modified 資源的最后修改日期時(shí)間
Allow: GET, HEAD
Content-Encoding: gzip
Content-Language: zh-CN 首部字段 Content-Language 會(huì)告知客戶端,實(shí)體主體使用的自然語(yǔ)言(指中文或英文等語(yǔ)言)。
Content-Length: 15000 首部字段 Content-Length 表明了實(shí)體主體部分的大小(單位是字節(jié))。對(duì)實(shí)體主體進(jìn)行內(nèi)容編碼傳輸時(shí),不能再使用 Content-Length首部字段。
Content-Location: http://www.sample.com/index.html 首部字段 Content-Location 給出與報(bào)文主體部分相對(duì)應(yīng)的 URI。和首部字段 Location 不同,Content-Location 表示的是報(bào)文主體返回資源對(duì)應(yīng)的 URI。
Content-MD5: OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==首部字段 Content-MD5 是一串由 MD5 算法生成的值,其目的在于檢查報(bào)文主體在傳輸過程中是否保持完整,以及確認(rèn)傳輸?shù)竭_(dá)。
Content-Range: bytes 5001-10000/10000 針對(duì)范圍請(qǐng)求,返回響應(yīng)時(shí)使用的首部字段 Content-Range,能告知客戶端作為響應(yīng)返回的實(shí)體的哪個(gè)部分符合范圍請(qǐng)求。字段值以字節(jié)為單位,表示當(dāng)前發(fā)送部分及整個(gè)實(shí)體大小。
Content-Type: text/html; charset=UTF-8 首部字段 Content-Type 說明了實(shí)體主體內(nèi)對(duì)象的媒體類型。和首部字段 Accept 一樣,字段值用 type/subtype 形式賦值。參數(shù) charset 使用 iso-8859-1 或 euc-jp 等字符集進(jìn)行賦值。
Expires: Mon, 10 Jul 2017 15:50:06 GMT
Last-Modified: Mon, 10 Jul 2017 15:50:06 GMT 首部字段 Last-Modified 指明資源最終修改的時(shí)間。一般來說,這個(gè)值就是 Request-URI 指定資源被修改的時(shí)間。但類似使用 CGI 腳本進(jìn)行動(dòng)態(tài)數(shù)據(jù)處理時(shí),該值有可能會(huì)變成數(shù)據(jù)最終修改時(shí)的時(shí)間。
首部字段名 說明 首部類型 Set-Cookie 開始狀態(tài)管理所使用的 Cookie 信息 響應(yīng)首部字段 Cookie 服務(wù)器接收到的 Cookie 信息 請(qǐng)求首部字段
Set-Cookie: status=enable; expires=Mon, 10 Jul 2017 15:50:06 GMT; path=/;
下面的表格列舉了 Set-Cookie 的字段值。
屬性 說明 NAME=VALUE 賦予 Cookie 的名稱和其值(必需項(xiàng)) expires=DATE Cookie 的有效期(若不明確指定則默認(rèn)為瀏覽器關(guān)閉前為止) path=PATH 將服務(wù)器上的文件目錄作為Cookie的適用對(duì)象(若不指定則默認(rèn)為文檔所在的文件目錄) domain=域名 作為 Cookie 適用對(duì)象的域名 (若不指定則默認(rèn)為創(chuàng)建 Cookie的服務(wù)器的域名) Secure 僅在 HTTPS 安全通信時(shí)才會(huì)發(fā)送 Cookie HttpOnly 加以限制,使 Cookie 不能被 JavaScript 腳本訪問
Cookie 的 path 屬性可用于限制指定 Cookie 的發(fā)送范圍的文件目錄。
Cookie 的 secure 屬性用于限制 Web 頁(yè)面僅在 HTTPS 安全連接時(shí),才可以發(fā)送 Cookie。
Cookie: status=enable 首部字段 Cookie 會(huì)告知服務(wù)器,當(dāng)客戶端想獲得 HTTP 狀態(tài)管理支持時(shí),就會(huì)在請(qǐng)求中包含從服務(wù)器接收到的 Cookie。接收到多個(gè) Cookie 時(shí),同樣可以以多個(gè) Cookie 形式發(fā)送。
HTTP 首部字段是可以自行擴(kuò)展的。所以在 Web 服務(wù)器和瀏覽器的應(yīng)用上,會(huì)出現(xiàn)各種非標(biāo)準(zhǔn)的首部字段。 以下是最為常用的首部字段。
X-Frame-Options: DENY 首部字段 X-Frame-Options 屬于 HTTP 響應(yīng)首部,用于控制網(wǎng)站內(nèi)容在其他 Web 網(wǎng)站的 Frame 標(biāo)簽內(nèi)的顯示問題。其主要目的是為了防止點(diǎn)擊劫持(clickjacking)攻擊。首部字段 X-Frame-Options 有以下兩個(gè)可指定的字段值:
X-XSS-Protection: 1 首部字段 X-XSS-Protection 屬于 HTTP 響應(yīng)首部,它是針對(duì)跨站腳本攻擊(XSS)的一種對(duì)策,用于控制瀏覽器 XSS 防護(hù)機(jī)制的開關(guān)。首部字段 X-XSS-Protection 可指定的字段值如下:
DNT: 1 首部字段 DNT 屬于 HTTP 請(qǐng)求首部,其中 DNT 是 Do Not Track 的簡(jiǎn)稱,意為拒絕個(gè)人信息被收集,是表示拒絕被精準(zhǔn)廣告追蹤的一種方法。首部字段 DNT 可指定的字段值如下:
由于首部字段 DNT 的功能具備有效性,所以 Web 服務(wù)器需要對(duì) DNT做對(duì)應(yīng)的支持。
P3P: CP="CAO DSP LAW CURa ADMa DEVa TAIa PSAa PSDa IVAa IVDa OUR BUS IND 首部字段 P3P 屬于 HTTP 響應(yīng)首部,通過利用 P3P(The Platform for Privacy Preferences,在線隱私偏好平臺(tái))技術(shù),可以讓 Web 網(wǎng)站上的個(gè)人隱私變成一種僅供程序可理解的形式,以達(dá)到保護(hù)用戶隱私的目的。 要進(jìn)行 P3P 的設(shè)定,需按以下操作步驟進(jìn)行:
類別 原因短語(yǔ) 1xx Informational(信息性狀態(tài)碼) 接收的請(qǐng)求正在處理 2xx Success(成功狀態(tài)碼) 請(qǐng)求正常處理完畢 3xx Redirection(重定向狀態(tài)碼) 需要進(jìn)行附加操作以完成請(qǐng)求 4xx Client Error(客戶端錯(cuò)誤狀態(tài)碼) 服務(wù)器無(wú)法處理請(qǐng)求 5xx Server Error(服務(wù)器錯(cuò)誤狀態(tài)碼) 服務(wù)器處理請(qǐng)求出錯(cuò)
我們可以自行改變 RFC2616 中定義的狀態(tài)碼或者服務(wù)器端自行創(chuàng)建狀態(tài)碼,只要遵守狀態(tài)碼的類別定義就可以了。
HTTP 狀態(tài)碼種類繁多,數(shù)量達(dá)幾十種。其中最常用的有以下 14 種,一起來看看。
表示從客戶端發(fā)來的請(qǐng)求在服務(wù)器端被正常處理了。
表示客戶端進(jìn)行了范圍請(qǐng)求,而服務(wù)器成功執(zhí)行了這部分的 GET 請(qǐng)求。響應(yīng)報(bào)文中包含由 Content-Range 首部字段指定范圍的實(shí)體內(nèi)容。
永久性重定向。表示請(qǐng)求的資源已被分配了新的 URI。以后應(yīng)使用資源現(xiàn)在所指的 URI。也就是說,如果已經(jīng)把資源對(duì)應(yīng)的 URI 保存為書簽了,這時(shí)應(yīng)該按 Location 首部字段提示的 URI 重新保存。
臨時(shí)重定向。該狀態(tài)碼與 302 Found 有著相同的含義。
表明對(duì)請(qǐng)求資源的訪問被服務(wù)器拒絕了。服務(wù)器端沒有必要給出詳細(xì)的拒絕理由,當(dāng)然也可以在響應(yīng)報(bào)文的實(shí)體主體部分對(duì)原因進(jìn)行描述。
表明服務(wù)器上無(wú)法找到請(qǐng)求的資源。除此之外,也可以在服務(wù)器端拒絕請(qǐng)求且不想說明理由的時(shí)候使用。
表明服務(wù)器端在執(zhí)行請(qǐng)求時(shí)發(fā)生了錯(cuò)誤。也可能是 Web 應(yīng)用存在的 bug 或某些臨時(shí)的故障。
表明服務(wù)器暫時(shí)處于超負(fù)載或正在進(jìn)行停機(jī)維護(hù),現(xiàn)在無(wú)法處理請(qǐng)求。如果事先得知解除以上狀況需要的時(shí)間,最好寫入 Retry-After 首部字段再返回給客戶端。
HTTP 報(bào)文結(jié)構(gòu)
大家請(qǐng)仔細(xì)看看上面示例中,各個(gè)組成部分對(duì)應(yīng)的內(nèi)容。 接著,我們來看看報(bào)文和實(shí)體的概念。如果把 HTTP 報(bào)文想象成因特網(wǎng)貨運(yùn)系統(tǒng)中的箱子,那么 HTTP 實(shí)體就是報(bào)文中實(shí)際的貨物。
我們可以看到,上面示例右圖中深紅色框的內(nèi)容就是報(bào)文的實(shí)體部分,而藍(lán)色框的兩部分內(nèi)容分別就是實(shí)體首部和實(shí)體主體。而左圖中粉紅框內(nèi)容就是報(bào)文主體。 通常,報(bào)文主體等于實(shí)體主體。只有當(dāng)傳輸中進(jìn)行編碼操作時(shí),實(shí)體主體的內(nèi)容發(fā)生變化,才導(dǎo)致它和報(bào)文主體產(chǎn)生差異。
內(nèi)容編碼類型:
編碼方式 描述 gzip 表明實(shí)體采用 GNU zip 編碼 compress 表明實(shí)體采用 Unix 的文件壓縮程序 deflate 表明實(shí)體采用 zlib 的格式壓縮的 identity 表明沒有對(duì)實(shí)體進(jìn)行編碼,當(dāng)沒有 Content-Encoding 首部字段時(shí),默認(rèn)采用此編碼方式
內(nèi)容編碼是對(duì)報(bào)文的主體進(jìn)行的可逆變換,是和內(nèi)容的具體格式細(xì)節(jié)緊密相關(guān)的。 傳輸編碼也是作用在實(shí)體主體上的可逆變換,但使用它們是由于架構(gòu)方面的原因,同內(nèi)容的格式無(wú)關(guān)。使用傳輸編碼是為了改變報(bào)文中的數(shù)據(jù)在網(wǎng)絡(luò)上傳輸?shù)姆绞健?/p>
內(nèi)容編碼和傳輸編碼的對(duì)比
分塊編碼把報(bào)文分割成若干已知大小的塊。塊之間是緊挨著發(fā)送的,這樣就不需要在發(fā)送之前知道整個(gè)報(bào)文的大小了。分塊編碼是一種傳輸編碼,是報(bào)文的屬性。
分塊編碼與持久連接 若客戶端與服務(wù)器端之間不是持久連接,客戶端就不需要知道它在讀取的主體的長(zhǎng)度,而只需要讀取到服務(wù)器關(guān)閉主體連接為止。 當(dāng)使用持久連接時(shí),在服務(wù)器寫主體之前,必須知道它的大小并在 Content-Length 首部中發(fā)送。如果服務(wù)器動(dòng)態(tài)創(chuàng)建內(nèi)容,就可能在發(fā)送之前無(wú)法知道主體的長(zhǎng)度。 分塊編碼為這種困難提供了解決方案,只要允許服務(wù)器把主體分塊發(fā)送,說明每塊的大小就可以了。因?yàn)橹黧w是動(dòng)態(tài)創(chuàng)建的,服務(wù)器可以緩沖它的一部分,發(fā)送其大小和相應(yīng)的塊,然后在主體發(fā)送完之前重復(fù)這個(gè)過程。服務(wù)器可以用大小為 0 的塊作為主體結(jié)束的信號(hào),這樣就可以繼續(xù)保持連接,為下一個(gè)響應(yīng)做準(zhǔn)備。 來看看一個(gè)分塊編碼的報(bào)文示例:
分塊編碼的報(bào)文
MIME 中的 multipart(多部分)電子郵件報(bào)文中包含多個(gè)報(bào)文,它們合在一起作為單一的復(fù)雜報(bào)文發(fā)送。每一部分都是獨(dú)立的,有各自的描述其內(nèi)容的集,不同部分之間用分界字符串連接在一起。 相應(yīng)得,HTTP 協(xié)議中也采納了多部分對(duì)象集合,發(fā)送的一份報(bào)文主體內(nèi)可包含多種類型實(shí)體。 多部分對(duì)象集合包含的對(duì)象如下:
假設(shè)你正在下載一個(gè)很大的文件,已經(jīng)下了四分之三,忽然網(wǎng)絡(luò)中斷了,那下載就必須重頭再來一遍。為了解決這個(gè)問題,需要一種可恢復(fù)的機(jī)制,即能從之前下載中斷處恢復(fù)下載。要實(shí)現(xiàn)該功能,這就要用到范圍請(qǐng)求。 有了范圍請(qǐng)求, HTTP 客戶端可以通過請(qǐng)求曾獲取失敗的實(shí)體的一個(gè)范圍(或者說一部分),來恢復(fù)下載該實(shí)體。當(dāng)然這有一個(gè)前提,那就是從客戶端上一次請(qǐng)求該實(shí)體到這一次發(fā)出范圍請(qǐng)求的時(shí)間段內(nèi),該對(duì)象沒有改變過。例如:
GET /bigfile.html HTTP/1.1
Host: www.sample.com
Range: bytes=20224-
···
實(shí)體范圍請(qǐng)求示例
上面示例中,客戶端請(qǐng)求的是文檔開頭20224字節(jié)之后的部分。
HTTP 通信時(shí),除客戶端和服務(wù)器外,還有一些用于協(xié)助通信的應(yīng)用程序。如下列出比較重要的幾個(gè):代理、緩存、網(wǎng)關(guān)、隧道、Agent 代理。
代理
HTTP 代理服務(wù)器是 Web 安全、應(yīng)用集成以及性能優(yōu)化的重要組成模塊。代理位于客戶端和服務(wù)器端之間,接收客戶端所有的 HTTP 請(qǐng)求,并將這些請(qǐng)求轉(zhuǎn)發(fā)給服務(wù)器(可能會(huì)對(duì)請(qǐng)求進(jìn)行修改之后再進(jìn)行轉(zhuǎn)發(fā))。對(duì)用戶來說,這些應(yīng)用程序就是一個(gè)代理,代表用戶訪問服務(wù)器。 出于安全考慮,通常會(huì)將代理作為轉(zhuǎn)發(fā)所有 Web 流量的可信任中間節(jié)點(diǎn)使用。代理還可以對(duì)請(qǐng)求和響應(yīng)進(jìn)行過濾,安全上網(wǎng)或綠色上網(wǎng)。
瀏覽器第一次請(qǐng)求:
瀏覽器第一次請(qǐng)求
瀏覽器再次請(qǐng)求:
瀏覽器再次請(qǐng)求
Web 緩存或代理緩存是一種特殊的 HTTP 代理服務(wù)器,可以將經(jīng)過代理傳輸?shù)某S梦臋n復(fù)制保存起來。下一個(gè)請(qǐng)求同一文檔的客戶端就可以享受緩存的私有副本所提供的服務(wù)了。客戶端從附近的緩存下載文檔會(huì)比從遠(yuǎn)程 Web 服務(wù)器下載快得多。
HTTP / FTP 網(wǎng)關(guān)
網(wǎng)關(guān)是一種特殊的服務(wù)器,作為其他服務(wù)器的中間實(shí)體使用。通常用于將 HTTP 流量轉(zhuǎn)換成其他的協(xié)議。網(wǎng)關(guān)接收請(qǐng)求時(shí)就好像自己是資源的源服務(wù)器一樣。客戶端可能并不知道自己正在跟一個(gè)網(wǎng)關(guān)進(jìn)行通信。
HTTP/SSL 隧道
隧道是會(huì)在建立起來之后,就會(huì)在兩條連接之間對(duì)原始數(shù)據(jù)進(jìn)行盲轉(zhuǎn)發(fā)的 HTTP 應(yīng)用程序。HTTP 隧道通常用來在一條或多條 HTTP 連接上轉(zhuǎn)發(fā)非 HTTP 數(shù)據(jù),轉(zhuǎn)發(fā)時(shí)不會(huì)窺探數(shù)據(jù)。 HTTP 隧道的一種常見用途就是通過 HTTP 連接承載加密的安全套接字層(SSL)流量,這樣 SSL 流量就可以穿過只允許 Web 流量通過的防火墻了。
自動(dòng)搜索引擎“網(wǎng)絡(luò)蜘蛛”
Agent 代理是代表用戶發(fā)起 HTTP 請(qǐng)求的客戶端應(yīng)用程序。所有發(fā)布 Web 請(qǐng)求的應(yīng)用程序都是 HTTP Agent 代理。
原文鏈接:https://www.jianshu.com/p/6e9e4156ece3
TTP(Hypertext Transfer Protocol,超文本傳輸協(xié)議)是互聯(lián)網(wǎng)中使用最廣泛的通信協(xié)議之一,它定義了客戶端與服務(wù)器之間的通信規(guī)則。無(wú)論是瀏覽網(wǎng)頁(yè)、調(diào)用 API、下載文件,還是進(jìn)行各種在線交互,HTTP 都是不可或缺的基礎(chǔ)協(xié)議。HTTP 協(xié)議基于請(qǐng)求-響應(yīng)模型工作,其中客戶端發(fā)出請(qǐng)求,服務(wù)器返回響應(yīng)。HTTP 請(qǐng)求方法定義了客戶端希望執(zhí)行的操作類型,每種請(qǐng)求方法都有特定的用途和行為。
在 HTTP/1.1 中,標(biāo)準(zhǔn)定義了多種請(qǐng)求方法,每種方法適用于不同的場(chǎng)景。本文將詳細(xì)介紹九種 HTTP 請(qǐng)求方法:GET、POST、PUT、DELETE、PATCH、HEAD、CONNECT、OPTIONS 和 TRACE。這些方法在 Web 開發(fā)和 API 設(shè)計(jì)中扮演著重要角色。通過理解這些請(qǐng)求方法的功能和使用場(chǎng)景,開發(fā)者可以更好地設(shè)計(jì)和優(yōu)化網(wǎng)絡(luò)應(yīng)用程序。
GET 方法是 HTTP 中最常用的請(qǐng)求方法之一,幾乎在所有的 Web 應(yīng)用中都能看到它的身影。GET 請(qǐng)求的主要作用是從服務(wù)器獲取資源,例如網(wǎng)頁(yè)、圖片、視頻等。當(dāng)用戶在瀏覽器中輸入一個(gè) URL 并按下回車鍵時(shí),瀏覽器便會(huì)向服務(wù)器發(fā)送一個(gè) GET 請(qǐng)求,要求獲取該 URL 對(duì)應(yīng)的資源。服務(wù)器處理請(qǐng)求后,會(huì)將資源發(fā)送回客戶端,通常是 HTML、CSS、JavaScript 文件或其他媒體內(nèi)容。
GET 方法的主要作用是從服務(wù)器請(qǐng)求數(shù)據(jù),而不會(huì)對(duì)服務(wù)器上的資源進(jìn)行任何修改。換句話說,GET 請(qǐng)求是"無(wú)副作用"的,不會(huì)改變服務(wù)器的狀態(tài)。GET 請(qǐng)求通常用于以下場(chǎng)景:
示例:
GET /index.html HTTP/1.1
Host: www.example.com
在上述示例中,客戶端通過 GET 請(qǐng)求從服務(wù)器獲取 index.html 文件。服務(wù)器在處理該請(qǐng)求后,會(huì)返回相應(yīng)的 HTML 文件給客戶端。
GET 請(qǐng)求廣泛應(yīng)用于 Web 開發(fā)中,尤其是在需要從服務(wù)器獲取數(shù)據(jù)的場(chǎng)景中。例如:
示例:
GET /search?q=http GET method HTTP/1.1
Host: www.searchengine.com
示例:
GET /product/12345 HTTP/1.1
Host: www.onlinestore.com
GET 請(qǐng)求的一個(gè)重要特性是可以被緩存。瀏覽器或中間代理服務(wù)器可以緩存 GET 請(qǐng)求的響應(yīng),以減少重復(fù)請(qǐng)求服務(wù)器的次數(shù),從而提高性能并降低帶寬消耗。HTTP 協(xié)議中定義了多種緩存機(jī)制,例如 ETag、Last-Modified 等,它們用于標(biāo)識(shí)資源的狀態(tài),判斷資源是否已改變。
緩存示例:
GET /logo.png HTTP/1.1
Host: www.example.com
If-None-Match: "abc123"
如果服務(wù)器返回的 ETag 與緩存中的 ETag 匹配,瀏覽器將直接使用緩存中的資源,而不重新下載文件。這不僅節(jié)省了帶寬,還加快了頁(yè)面加載速度。
GET 請(qǐng)求中常見的一種形式是通過 URL 參數(shù)或查詢字符串傳遞數(shù)據(jù)。查詢字符串通常附加在 URL 的末尾,以 ? 開頭,參數(shù)與值之間用 = 連接,多個(gè)參數(shù)之間用 & 分隔。
示例:
GET /search?q=HTTP+GET+method&sort=latest HTTP/1.1
Host: www.example.com
在上述請(qǐng)求中,查詢字符串 q=HTTP+GET+method&sort=latest 包含了兩個(gè)參數(shù):q 和 sort,分別表示搜索關(guān)鍵詞和排序方式。這種方式適合傳遞簡(jiǎn)單的鍵值對(duì)數(shù)據(jù),但由于查詢字符串會(huì)暴露在 URL 中,因此不適合傳輸敏感信息。
盡管 GET 請(qǐng)求廣泛使用,但在安全性方面需要注意以下幾點(diǎn):
為了增強(qiáng)安全性,建議在傳輸敏感數(shù)據(jù)時(shí)使用 POST 方法,并通過 HTTPS 加密通信。
POST 方法用于向服務(wù)器發(fā)送數(shù)據(jù),通常是為了提交表單、上傳文件、或調(diào)用 API 接口以進(jìn)行數(shù)據(jù)處理。與 GET 方法不同,POST 請(qǐng)求的數(shù)據(jù)不會(huì)附加在 URL 中,而是包含在請(qǐng)求體中。因此,POST 方法適合傳輸較大或敏感的數(shù)據(jù)。
POST 方法的典型使用場(chǎng)景包括:
示例:
POST /submit-form HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
username=johndoe&password=secret123
示例:
POST /upload HTTP/1.1
Host: www.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="example.jpg"
Content-Type: image/jpeg
(binary file data)
------WebKitFormBoundary--
示例:
POST /api/users HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"username": "johndoe",
"email": "johndoe@example.com",
"password": "secret123"
}
POST 請(qǐng)求是非冪等的,這意味著重復(fù)發(fā)送相同的 POST 請(qǐng)求可能會(huì)產(chǎn)生不同的結(jié)果。例如,重復(fù)提交訂單或評(píng)論可能會(huì)導(dǎo)致服務(wù)器生成多個(gè)相同的記錄。由于這一特性,開發(fā)者在設(shè)計(jì) API 時(shí)通常需要考慮如何防止重復(fù)提交的問題,例如使用唯一性約束、token 驗(yàn)證等手段。
與 GET 請(qǐng)求相比,POST 請(qǐng)求在安全性方面有一些顯著的優(yōu)勢(shì):
盡管如此,POST 請(qǐng)求仍然需要配合 HTTPS 協(xié)議使用,以確保數(shù)據(jù)在傳輸過程中的安全性。使用 HTTPS 可以加密數(shù)據(jù),防止在傳輸過程中被竊取或篡改。
PUT 方法通常用于更新服務(wù)器上的資源。與 POST 方法不同,PUT 請(qǐng)求是冪等的,意味著多次發(fā)送相同的 PUT 請(qǐng)求,服務(wù)器的資源狀態(tài)不會(huì)變化。PUT 方法可以用于創(chuàng)建或更新資源,通常用于更新現(xiàn)有資源的數(shù)據(jù)。
PUT 方法的典型使用場(chǎng)景包括:
示例:
PUT /api/users/123 HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"username": "johndoe",
"email": "newemail@example.com"
}
示例:
PUT /documents/456 HTTP/1.1
Host: www.example.com
Content-Type: text/plain
Updated document content...
PUT 方法是冪等的,這意味著相同的 PUT 請(qǐng)求無(wú)論執(zhí)行多少次,服務(wù)器上的資源狀態(tài)應(yīng)保持一致。例如,用戶修改個(gè)人資料后,如果重復(fù)發(fā)送相同的 PUT 請(qǐng)求,服務(wù)器上該用戶的資料應(yīng)保持不變,而不會(huì)生成多個(gè)相同的記錄。
PUT 請(qǐng)求通常用于更新現(xiàn)有資源,因此在安全性方面需要特別注意以下幾點(diǎn):
DELETE 方法用于刪除服務(wù)器上的指定資源。在 RESTful API 設(shè)計(jì)中,DELETE 方法通常用于移除指定的資源對(duì)象或數(shù)據(jù)。例如,刪除一篇文章、一條評(píng)論、或一個(gè)用戶賬戶等。DELETE 方法的冪等性特性決定了無(wú)論同一個(gè) DELETE 請(qǐng)求被執(zhí)行多少次,服務(wù)器上的資源狀態(tài)應(yīng)保持一致,即資源被刪除后,再次刪除操作不會(huì)產(chǎn)生任何新的效果。
DELETE 方法的典型使用場(chǎng)景包括:
DELETE 方法是冪等的,這意味著相同的 DELETE 請(qǐng)求無(wú)論執(zhí)行多少次,服務(wù)器上的資源狀態(tài)應(yīng)保持一致。例如,發(fā)送 DELETE 請(qǐng)求刪除一篇文章,如果文章已經(jīng)被刪除,再次發(fā)送相同的 DELETE 請(qǐng)求不會(huì)導(dǎo)致新的變化,服務(wù)器應(yīng)返回一個(gè)指示資源已不存在的響應(yīng)。
DELETE 請(qǐng)求涉及到資源的刪除操作,因此需要特別注意以下幾個(gè)方面的安全性問題:
PATCH 方法用于對(duì)服務(wù)器上的資源進(jìn)行部分更新。與 PUT 方法不同,PATCH 請(qǐng)求不需要包含完整的資源數(shù)據(jù),而只需要傳輸需要更新的部分字段。因此,PATCH 方法非常適合用于需要頻繁更新部分?jǐn)?shù)據(jù)的場(chǎng)景。
PATCH 方法的典型使用場(chǎng)景包括:
示例:
PATCH /api/users/123 HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"email": "newemail@example.com"
}
示例:
PATCH /documents/456 HTTP/1.1
Host: www.example.com
Content-Type: application/json
{
"title": "Updated Document Title"
}
PATCH 方法通常被認(rèn)為是非冪等的,這意味著相同的 PATCH 請(qǐng)求被執(zhí)行多次可能會(huì)產(chǎn)生不同的結(jié)果。例如,如果一個(gè) PATCH 請(qǐng)求是對(duì)字符串?dāng)?shù)據(jù)進(jìn)行追加操作,那么重復(fù)執(zhí)行相同的請(qǐng)求將會(huì)導(dǎo)致字符串的內(nèi)容被多次追加,產(chǎn)生不同的結(jié)果。
然而,也有特定情況下的 PATCH 請(qǐng)求是冪等的,例如只是對(duì)某個(gè)字段的值進(jìn)行覆蓋更新。在這種情況下,PATCH 請(qǐng)求的冪等性與 PUT 方法類似。
PATCH 請(qǐng)求主要用于部分更新,因此在安全性方面需注意以下幾點(diǎn):
HEAD 方法與 GET 方法非常相似,但它只請(qǐng)求資源的首部信息,而不包含資源的具體內(nèi)容。HEAD 請(qǐng)求的響應(yīng)中只有狀態(tài)行和頭部字段,不返回消息體。HEAD 方法通常用于在不下載資源的情況下獲取資源的元數(shù)據(jù),如檢查資源是否存在、獲取資源的大小或類型等。
HEAD 方法的典型使用場(chǎng)景包括:
示例:
HEAD /files/sample.pdf HTTP/1.1
Host: www.example.com
示例:
HEAD /api/documents/456 HTTP/1.1
Host: www.example.com
HEAD 方法的一個(gè)顯著特點(diǎn)是它不會(huì)返回消息體,因此在獲取資源元數(shù)據(jù)時(shí),HEAD 請(qǐng)求比 GET 請(qǐng)求更加高效。此外,由于 HEAD 請(qǐng)求不會(huì)返回資源內(nèi)容,它通常被用作緩存控制的手段。例如,通過 HEAD 請(qǐng)求檢查資源的 Last-Modified 或 ETag 頭部字段,客戶端可以決定是否需要重新下載資源。
CONNECT 方法用于建立一個(gè)到服務(wù)器的隧道連接,通常用于 HTTP 與 HTTPS 的代理請(qǐng)求。CONNECT 請(qǐng)求會(huì)將客戶端的連接轉(zhuǎn)換為一個(gè)雙向通信的通道,允許客戶端與目標(biāo)服務(wù)器之間傳遞任意數(shù)據(jù)而不受代理服務(wù)器的影響。最常見的應(yīng)用場(chǎng)景是通過 HTTP 代理訪問 HTTPS 站點(diǎn)。
CONNECT 方法的典型使用場(chǎng)景包括:
示例:
CONNECT www.example.com:443 HTTP/1.1
Host: www.example.com
當(dāng)代理服務(wù)器收到這個(gè)請(qǐng)求后,會(huì)建立一個(gè)與目標(biāo)服務(wù)器的 TCP 連接,并將后續(xù)的所有數(shù)據(jù)直接傳遞給目標(biāo)服務(wù)器。這種方式允許客戶端與目標(biāo)服務(wù)器之間的通信保持安全性和私密性,因?yàn)榇矸?wù)器只負(fù)責(zé)傳遞數(shù)據(jù),而不進(jìn)行解析或修改。
由于 CONNECT 方法用于創(chuàng)建一個(gè)隧道連接,它能夠有效地維護(hù)客戶端與服務(wù)器之間的通信隱私。然而,CONNECT 方法也可能被濫用。例如,惡意用戶可以利用 CONNECT 方法繞過防火墻或其他網(wǎng)絡(luò)安全措施,進(jìn)行未經(jīng)授權(quán)的訪問。因此,許多代理服務(wù)器在使用 CONNECT 方法時(shí)會(huì)對(duì)目標(biāo)端口或目標(biāo)域名進(jìn)行限制,防止濫用。
OPTIONS 方法用于查詢服務(wù)器支持的請(qǐng)求方法或特定資源所支持的功能。它通常用于檢查服務(wù)器的能力,確定哪些請(qǐng)求方法可以被安全地執(zhí)行在指定資源上。OPTIONS 請(qǐng)求的響應(yīng)通常包括 Allow 頭部字段,列出服務(wù)器支持的請(qǐng)求方法。
OPTIONS 方法的典型使用場(chǎng)景包括:
示例:
OPTIONS /api/users HTTP/1.1
Host: api.example.com
響應(yīng)示例:
HTTP/1.1 204 No Content
Allow: GET, POST, PUT, DELETE
示例:
OPTIONS /documents/456 HTTP/1.1
Host: www.example.com
響應(yīng)示例:
HTTP/1.1 200 OK
Allow: GET, POST, DELETE, OPTIONS
OPTIONS 方法廣泛用于 CORS 機(jī)制中,以確保跨域請(qǐng)求的安全性和合規(guī)性。通過預(yù)檢請(qǐng)求,服務(wù)器可以控制哪些外部來源和請(qǐng)求方法可以訪問其資源,從而避免跨站請(qǐng)求偽造(CSRF)攻擊。
此外,OPTIONS 方法也可以用于測(cè)試和診斷服務(wù)器的配置,幫助開發(fā)者或管理員了解服務(wù)器的請(qǐng)求處理能力。
TRACE 方法用于在服務(wù)器上發(fā)起一個(gè)回環(huán)測(cè)試,即服務(wù)器將收到的請(qǐng)求原樣返回給客戶端。TRACE 方法的主要用途是診斷或調(diào)試,幫助客戶端檢查請(qǐng)求在傳輸過程中是否被修改或損壞。
TRACE 請(qǐng)求的典型使用場(chǎng)景包括:
示例:
TRACE /api/resource HTTP/1.1
Host: www.example.com
響應(yīng)示例:
HTTP/1.1 200 OK
Content-Type: message/http
TRACE /api/resource HTTP/1.1
Host: www.example.com
User-Agent: MyBrowser/1.0
由于 TRACE 方法會(huì)將請(qǐng)求的所有信息,包括可能包含的敏感數(shù)據(jù),如 Cookies 或 Authorization 頭部,返回給客戶端,這可能導(dǎo)致信息泄露。攻擊者可以利用 TRACE 方法實(shí)施跨站點(diǎn)跟蹤攻擊(Cross-Site Tracing,XST),獲取用戶的敏感信息。因此,許多現(xiàn)代的 Web 服務(wù)器默認(rèn)禁用 TRACE 方法以防止?jié)撛诘陌踩L(fēng)險(xiǎn)。
CORS ( Cross Origin Resource Sharing,跨域資源共享)機(jī)制允許Web應(yīng)用服務(wù)器進(jìn)行跨域訪問控制,從而使跨域數(shù)據(jù)傳輸?shù)靡园踩M(jìn)行。瀏覽器支持在API容器中(如XMLHttpRequest或Fetch )使用CORS,以降低跨域HTTP請(qǐng)求所帶來的風(fēng)險(xiǎn)。
本節(jié)將介紹如何在Spring Boot應(yīng)用中,實(shí)現(xiàn)跨域訪問資源。
當(dāng)一個(gè)資源從與該資源本身所在的服務(wù)器不同的域或端口請(qǐng)求一一個(gè)資源時(shí), 資源會(huì)發(fā)起- - 個(gè)跨域HTTP請(qǐng)求。
比如,站點(diǎn)ht://example-a.com 的某HTML頁(yè)面通過<img>的src請(qǐng)求htp://example-b.com/image.jpg。網(wǎng)絡(luò)上的許多頁(yè)面都會(huì)加載來自不同域的CSS樣式表、圖像和腳本等資源。
W3C制定了CORS的相關(guān)規(guī)范,見hts://ww.w3.org/TR/cors/。出于安全考慮,瀏覽器會(huì)限制從腳本內(nèi)發(fā)起的跨域HTTP請(qǐng)求。例如,XMLHttpRequest 和Fetch遵循同源策略。因此,使用XMLHtpRequest或Fetch的Web應(yīng)用程序只能將HTTP請(qǐng)求發(fā)送到其自己的域。為了改進(jìn)Web應(yīng)用程序,開發(fā)人員要求瀏覽器廠商允許跨域請(qǐng)求。
識(shí)別是否具有跨域行為,是由同源政策決定的。同源政策由Netscape 公司引入瀏覽器。目前,所有瀏覽器都實(shí)行這個(gè)政策。所謂“同源”, 指的是“三個(gè)相同”。
協(xié)議相同。
●域名相同。
● 端口相同。
舉例來說,htp://example.com/page.html 這個(gè)網(wǎng)址,協(xié)議是htp://, 域名是www.example.com,端口是80 (默認(rèn)端口可以省略)。它的同源情況如下。
http://example. com/other.html:同源。
● ht://www.example.com/other.html: 不同源,域名不同。
● htp://v2.example.com/other.html: 不同源,域名不同。
● htp://example.com:81/other.html: 不同源,端口不同。
在微服務(wù)的架構(gòu)里面,由于每個(gè)服務(wù)都在其自身的源中運(yùn)行,因此,很容易就會(huì)遇到來自多個(gè)來源的客戶端Web應(yīng)用程序來訪問服務(wù)的問題(即跨域訪問)。例如,- -個(gè)瀏覽器客戶端從“客戶”
微服務(wù)器訪問“客戶”,并從“訂單”微服務(wù)器訪問訂單歷史記錄,這種做法在微服務(wù)領(lǐng)域非常普遍。
Spring MVC支持CORS的開箱即用的功能。主要有兩種實(shí)現(xiàn)跨域訪問的方式。
1.方法級(jí)別的跨域訪問
Spring Boot提供了一種簡(jiǎn)單的聲明式方法來實(shí)現(xiàn)跨域請(qǐng)求。以下示例顯示如何使用@CrossOr-igin注解,來啟用允許跨域訪問某些接口。
import org. springf ramework. web. bind. annotation. CrossOrigin;
@CrossOrigin(origins="*", maxAge=3600) // 允許所有域名訪問
@Controller
public class FileController {
//..
}
其中,origins="**意味著允許所有域名訪問(當(dāng)然,你也可以限定某個(gè)域名來訪問)。maxAge=3600是指有效期為3600秒。
2.全局跨域訪問
可以通過使用自定義的addCorsMappings(CorsRegistry)方法注冊(cè)WebMvcConfigurer bean來定義全局CORS配置。用法如下。
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer () {
@Override
public void addCorsMappings (CorsRegistry registry){
registry. addMapping ("/api/**");
};
}}
消息通信是企業(yè)信息集成中非常重要的一種方式。
消息的通信一般是由消息隊(duì)列系統(tǒng)( MessageQueuing System, MQ )或面向消息中間件( Message Oriented Middleware, MOM )來提供高效可靠的消息傳遞機(jī)制進(jìn)行平臺(tái)無(wú)關(guān)的數(shù)據(jù)交流,并可基于數(shù)據(jù)通信進(jìn)行分布式系統(tǒng)的集成。通過提供消息傳遞和消息排隊(duì)模型,可在分布環(huán)境下擴(kuò)展進(jìn)程間的通信,并支持多種通信協(xié)議、語(yǔ)言、應(yīng)用程序、硬件和軟件平臺(tái)。
通過使用MQ或MOM,通信雙方的程序(稱其為消息客戶程序)可以在不同的時(shí)間運(yùn)行,程序不在網(wǎng)絡(luò).上直接通話,而是間接地將消息放入MQ或MOM服務(wù)器的消息隊(duì)列中。因?yàn)槌绦蜷g沒有直接的聯(lián)系,所以它們不必同時(shí)運(yùn)行:消息放入適當(dāng)?shù)年?duì)列時(shí),目標(biāo)程序不需要正在運(yùn)行;即使目標(biāo)程序在運(yùn)行,也不意味著要立即處理該消息。
消息客戶程序之間通過將消息放入消息隊(duì)列或從消息隊(duì)列中取出消息來進(jìn)行通信。客戶程序不直接與其他程序通信,避免了網(wǎng)絡(luò)通信的復(fù)雜性。消息隊(duì)列和網(wǎng)絡(luò)通信的維護(hù)工作由MQ或MOM完成。
常見的MQ或MOM產(chǎn)品有Java Message Service、 Apache ActiveMQ、Apache RocketMQ、RabbitMQ、Apache Kafka等。
對(duì)于Spring應(yīng)用而言,Spring Boot針對(duì)Java Message Service、RabbitMQ、 Apache Kafka等提供了開箱即用的支持。
Java Message Service ( JMS ) API是- -個(gè) Java面向消息中間件的API,用于兩個(gè)或多個(gè)客戶端之間發(fā)送消息。
JMS的目標(biāo)包括:
●包含實(shí)現(xiàn)復(fù)雜企業(yè)應(yīng)用所需要的功能特性;
●定義了企業(yè)消息概念和功能的一組通用集合;
●最小化企業(yè)消息產(chǎn)品的概念,以降低學(xué)習(xí)成本。
最大化消息應(yīng)用的可移植性。
JMS支持企業(yè)消息產(chǎn)品提供以下兩種主要的消息風(fēng)格。
●點(diǎn)對(duì)點(diǎn) (Point-to-Point, PTP )消息風(fēng)格:允許一個(gè)客戶端通過-一個(gè)叫“隊(duì)列( queue)”的中間抽象發(fā)送一個(gè)消息給另- 一個(gè)客戶端。發(fā)送消息的客戶端將-一個(gè)消息發(fā)送 到指定的隊(duì)列中,接收消息的客戶端從這個(gè)隊(duì)列中抽取消息。
●發(fā)布訂閱( Publish/Subscribe, Pub/Sub )消息風(fēng)格:允許-一個(gè)客戶端通過-一個(gè)叫“主題( topic )”的中間抽象發(fā)送一個(gè)消息給多個(gè)客 戶端。發(fā)送消息的客戶端將一個(gè)消 息發(fā)布到指定的主題中,然后這個(gè)消息將被投遞到所有訂閱了這個(gè)主題的客戶端。
在Spring Boot應(yīng)用中使用JMS,通常需要以下幾個(gè)步驟。
1.使用JNDI ConnectionFactory
在應(yīng)用程序中,Spring Boot將嘗試使用JNDI找到JMS ConnectionFactory。 默認(rèn)情況下,將檢查位置java:/JmsXA和java:/XAConnectionFactory。如果需要指定其他位置,可以使用spring.jms.jndi-name屬性。
spring.jms.jndi-name=java:/MyConnectionFactory
2.發(fā)送消息
Spring的JmsTemplate是自動(dòng)配置的,可以將其直接自動(dòng)裝配到自己的bean中。
import org. springf ramework. beans. factory . annotation. Autowired;
import org. spr ingframework. jms . core . JmsTemplate;
import org. spr ingframework. stereotype . Component;
@Component
public class MyBean
private final JmsTemplate jmsTemplate;
@Autowi red
public MyBean (JmsTemplate jmsTemplate) {
this. jmsTemplate=jmsTemplate;
3.接收消息
在JMS架構(gòu)中,可以使用@JmsListener來注解任何bean,以創(chuàng)建偵聽器端點(diǎn)。如果沒有定義JmsListenerContainerFactory,則會(huì)自動(dòng)配置默認(rèn)值。如果定義了DestinationResolver 或Message-Converter bean,則它們將自動(dòng)關(guān)聯(lián)到默認(rèn)工廠。
默認(rèn)工廠是事務(wù)性的。如果在JtaTransactionManager 存在的基礎(chǔ)架構(gòu)中運(yùn)行,則默認(rèn)情況下將
與偵聽器容器相關(guān)聯(lián)。如果沒有,sessionTransacted 標(biāo)志將被啟用。在后一種情況下, 可以通過在
偵聽器方法(或其代理)上添加@Transactional來將本地?cái)?shù)據(jù)存儲(chǔ)事務(wù)關(guān)聯(lián)到傳入消息的處理。這
將確保在本地事務(wù)完成后確認(rèn)傳入的消息。這還包括發(fā)送在同-一個(gè)JMS會(huì)話上執(zhí)行的響應(yīng)消息。
以下案例在someQueue目標(biāo)上創(chuàng)建一個(gè) 偵聽器端點(diǎn)。
@Component
public class MyBean {
@JmsListener (destination="someQueue")
public void processMessage (String content) {
}
}
RabbitMQ是更高級(jí)別的消息中間件,實(shí)現(xiàn)了Advanced Message Queuing Protocol( AMQP )協(xié)議。
Spring AMQP項(xiàng)目將核心Spring 概念應(yīng)用于基于AMQP的消息傳遞解決方案的開發(fā)。Spring Boot提供了幾種通過RabbitMQ與AMQP協(xié)同工作的開箱即用的方式,包括spring-boot- sarter-amqp等各種Starter。
1.配置RabbitMQ
RabbitMQ的配置由外部配置屬性spring.rabbitmq.*來控制。例如,可以在application.properties中聲明以下部分。
spring. rabbi tmq. host=localhost
spring. rabbi tmq.port=5672
spring. rabbi tmq . username=admin
spring. rabbi tmq. password=secret
2.發(fā)送消息
Spring 的AmqpTemplate和AmqpAdmin是自動(dòng)配置的,可以將它們直接自動(dòng)裝配到自己的bean中。
import org.spr ingframework. amgp . core . AmqpAdmin;
import org. spr ingf ramework. amqp. core . AmqpTemplate;
import org. springframework.beans. factory . annotation. Autowired;
import org. springframework. stereotype. Component;
@Component
public class MyBean
private final AmqpAdmin amqpAdmin;
private final AmqpTemplate amqpTemplate;
@Autowired
public MyBean (AmqpAdmin amqpAdmin, AmqpTemplate amqpTemplate) {
this . amqpAdmin=amqpAdmin;
this . amqpTemplate=amqpTemplate;
}
}
3.接收消息
當(dāng)Rabbit 的基礎(chǔ)架構(gòu)存在時(shí),可以使用@RabbitListener來注解bean,以創(chuàng)建偵聽器端點(diǎn)。如果沒有定義RabbitListenerContainerFactory,則會(huì)自動(dòng)配置默認(rèn)的SimpleRabitListenerContainerFactory。可以使用spring.rabbitmq.listener.type屬性切換到直接容器。如果MessageConverter或MessageRecoverer bean被定義,它們將自動(dòng)關(guān)聯(lián)到默認(rèn)工廠。
以下示例是在someQueue隊(duì)列上創(chuàng)建-一個(gè)偵聽器端點(diǎn)。
@Component
public class MyBean
@RabbitListener (queues=" someQueue")
public void processMessage (String content) {
//...
}
}
下篇文章給大家介紹數(shù)據(jù)持文化和實(shí)現(xiàn)熱插撥兩部分內(nèi)容,歡迎大家來學(xué)習(xí)!!
也感謝大家支持!!
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。