HTTP協(xié)議詳解

日常的web開(kāi)發(fā)過(guò)程中,以及其他的開(kāi)發(fā)中,接觸到最多的網(wǎng)絡(luò)交互協(xié)議就是http協(xié)議,而http協(xié)議基于tcp的二度封裝協(xié)議,既然http協(xié)議如此重要,那么我
們就開(kāi)始系統(tǒng)的對(duì)http協(xié)議進(jìn)行掃盲學(xué)習(xí)吧

請(qǐng)求/響應(yīng)模型

http屬于請(qǐng)求/響應(yīng)模型,從某種意義上來(lái)說(shuō),Http協(xié)議永遠(yuǎn)都是客戶(hù)端發(fā)起請(qǐng)求,由服務(wù)器端接受請(qǐng)求處理并返回響應(yīng)報(bào)文。如果沒(méi)有客戶(hù)端發(fā)送請(qǐng)求到服務(wù)端,那么服務(wù)端無(wú)法將消息發(fā)送回客戶(hù)端的。而HTTP交互的流程圖如下,當(dāng)客戶(hù)端發(fā)送請(qǐng)求到服務(wù)端的時(shí)候,請(qǐng)求頭常見(jiàn)的包含有請(qǐng)求方式、URI、協(xié)議版本等,以及會(huì)攜帶MIME的消息內(nèi)容,服務(wù)端作為一個(gè)狀態(tài)行的方式響應(yīng),包括協(xié)議版本、編碼、元數(shù)據(jù)和實(shí)體數(shù)據(jù)等,這樣就完成了一個(gè)請(qǐng)求/響應(yīng)流程

HTTP的發(fā)展過(guò)程

1989年3月,蒂姆 ? 伯納斯 - 李提出了一種能讓遠(yuǎn)隔兩地的研究者們共享知識(shí)的設(shè)想,起初的理念是:借助多文檔之間相互關(guān)聯(lián)形成的超文本(HyperText),連成可相互參閱的 WWW(World Wide Web,萬(wàn)維網(wǎng))隨著HTML1.0的誕生,作為其中的超文本傳輸協(xié)議的HTTP正式誕生

Http/0.9:1990年誕生,作為HTTP最早的協(xié)議版本,但是由于當(dāng)時(shí)對(duì)于HTML相關(guān)web的定義未統(tǒng)一,該版本并不是正式版

HTTP/1.0:1996年5月份,隨著微軟公司與網(wǎng)景通信公司之間爆發(fā)的瀏覽器大戰(zhàn)越來(lái)越烈,HTML兼容多個(gè)瀏覽器的頭疼問(wèn)題出現(xiàn)了,但是針對(duì)網(wǎng)絡(luò)協(xié)議的正式版HTTP1.0出現(xiàn)了

HTTP/1.1:1997年1月份對(duì)于HTTP1.0的版本進(jìn)行了部分內(nèi)容的修訂,作為更標(biāo)準(zhǔn)化的協(xié)議出現(xiàn),也是目前為止依然主流的協(xié)議版本

HTTP/1.2:1999年,針對(duì)HTTP1.1的改進(jìn)版本出現(xiàn),1.2使用了SRV records 更好地支持負(fù)載平衡 ,改進(jìn)了之前只能基于表單的認(rèn)證方式,提供了Basic和Digest訪問(wèn)認(rèn)證,增加了一套新的accepted headers

HTTP/2.0:2013年8月份出了新一代的超文本傳輸協(xié)議的草案,與之前的HTTP1.x版本差距頗大,無(wú)法兼容,此協(xié)議針對(duì)連接的安全性做了很大的提升,而HTTP2.0的絕大多數(shù)請(qǐng)求基本都是走的HTTPS,所以一般情況下,不會(huì)直接用HTTP2.0,而是HTTPS

URI和URL

看到這可能絕大多數(shù)的人都很奇怪,URL我們都知道,比如我們?yōu)g覽一個(gè)網(wǎng)站,輸入的www.xxx.com的網(wǎng)址就是URL,那么URI是什么呢?其實(shí)我們要明白,URI是Uniform Resource Identifier 的縮寫(xiě),稱(chēng)之為統(tǒng)一資源標(biāo)示符,到這可能大概明白了,URL其實(shí)就是URI的一個(gè)子集而已,而URI主要分為Uniform、Resource和Identifier

Uniform:用來(lái)方便做多種不同類(lèi)型的資源得處理,而不需要根據(jù)上下文等方法識(shí)別訪問(wèn)方式,比如我們輸入網(wǎng)址的時(shí)候輸入的Http:

Resource:傳輸過(guò)程中可以用來(lái)區(qū)別其他類(lèi)型的文件的集合定義,資源是一個(gè)類(lèi)型的統(tǒng)稱(chēng),不僅僅是單一的

Identifier:表示當(dāng)前可以標(biāo)識(shí)的對(duì)象,也稱(chēng)之為標(biāo)示符

一個(gè)URI的例子如下:

ftp://ftp.is.co.za/rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc2396.txt
tel:+1-535-555-1212
telnet://192.168.1.16:80/
urn:oasis:names:specification:docbook:dtd:xml:4.1.2

而URI使用過(guò)程中,如果需要涵蓋全部信息或者準(zhǔn)確信息,就要正確使用URI的格式:


URI的格式.png
名稱(chēng) 作用 是否必選
登錄信息 指定用戶(hù)名和密碼作為從服務(wù)器端獲取資源時(shí)必要的登錄信息 Y
服務(wù)器地址 使用絕對(duì) URI 必須指定待訪問(wèn)的服務(wù)器地址 Y
服務(wù)器端口 連接服務(wù)器的端口 N
文件路徑 指定服務(wù)器上的文件路徑來(lái)定位特指的資源(UNLX系統(tǒng)) N
查詢(xún)字符串 可以作為URL攜帶的請(qǐng)求參數(shù)來(lái)協(xié)助定位具體文件資源 N
片段標(biāo)識(shí)符 通??蓸?biāo)記出已獲取資源中的子資源 N

無(wú)狀態(tài)協(xié)議

Http協(xié)議屬于一種不記錄狀態(tài)的協(xié)議,即無(wú)狀態(tài)協(xié)議,具體表現(xiàn)為,每次請(qǐng)求發(fā)起都會(huì)重新進(jìn)行連接,并不會(huì)根據(jù)之前的狀態(tài)或者持久化保持狀態(tài)。每當(dāng)有新的請(qǐng)求發(fā)送時(shí),就會(huì)有對(duì)應(yīng)的新響應(yīng)產(chǎn)生。協(xié)議本身并不保留之前一切的請(qǐng)求或響應(yīng)報(bào)文的信息。這是為了更快地處理大量事務(wù),確保協(xié)議的可伸縮性。但是Http雖然是無(wú)狀態(tài)協(xié)議,但是有保存狀態(tài)信息的需求,HTTP1.1開(kāi)始引入了Cookie技術(shù),使用cookie來(lái)代為管理狀態(tài)信息。

HTTP協(xié)議方法

Http協(xié)議支持通過(guò)不同的請(qǐng)求類(lèi)型--即協(xié)議方法來(lái)達(dá)成某種目的,實(shí)現(xiàn)功能,HTTP1.1支持的協(xié)議方法如下:

GET :獲取資源

Get方法用來(lái)訪問(wèn)已經(jīng)被URI識(shí)別的資源,指定的資源信息經(jīng)由服務(wù)端解析以后返回對(duì)應(yīng)的資源響應(yīng)內(nèi)容,也就是說(shuō)如果當(dāng)前訪問(wèn)的資源是文本等靜態(tài)資源,則會(huì)返回對(duì)應(yīng)的數(shù)據(jù),如果是網(wǎng)關(guān)等程序,則會(huì)返回對(duì)應(yīng)的結(jié)果。

POST:傳輸實(shí)體主體

在HTTP中推薦使用POST方法來(lái)傳遞我們需要傳輸?shù)膬?nèi)容或者實(shí)體信息,雖然GET方法可以添加查詢(xún)字符串來(lái)輔助傳遞一定的信息和參數(shù),但是要注意的是GET方法定義僅僅是希望根據(jù)查詢(xún)字符串來(lái)定位具體的資源,所以GET方法一般都希望得到快速響應(yīng),傳遞的數(shù)據(jù)的長(zhǎng)度有一定的限制

PUT:傳輸文件

HTTP協(xié)議中,PUT方法被定義出來(lái)用來(lái)朝服務(wù)端傳遞文件(上傳)使用的方法,要求在請(qǐng)求的報(bào)文中包含文件內(nèi)容,然后保存文件到請(qǐng)求的URI所在的位置上,但是由于HTTP1.1不帶有安全機(jī)制,所以一般當(dāng)前方法在HTTP協(xié)議上不開(kāi)放,類(lèi)似的協(xié)議如:Restful會(huì)開(kāi)放實(shí)現(xiàn)其他規(guī)范的操作

HEAD:獲得報(bào)文首部

HEAD方法和GET方法一樣,唯一的區(qū)別是GET方法返回完整的響應(yīng)信息,而HEAD方法不需要報(bào)文主體部分,因?yàn)榇朔椒▋H用來(lái)獲取頭信息,用來(lái)確認(rèn)URI是否有效或者觸發(fā)資源的緩存更新等

DELETE:刪除文件

DELETE方法和PUT方法是完全相反的定義,這里的作用是用來(lái)刪除指定請(qǐng)求URI上位置的資源文件,而和PUT一樣,在不帶有安全驗(yàn)證機(jī)制的情況下一般也是不開(kāi)放的

OPTIONS:詢(xún)問(wèn)支持的方法

OPTIONS方法使用場(chǎng)景比較特殊,一般情況下我們用來(lái)查詢(xún)針對(duì)請(qǐng)求URI指定的資源支持的方法有哪些(和跨域操作也有一定的聯(lián)系)

TRACE:追蹤路徑

TRACE方法是HTTP協(xié)議用來(lái)檢查和追蹤請(qǐng)求過(guò)程提供的方法,當(dāng)發(fā)送請(qǐng)求的時(shí)候,會(huì)在Max-Forwards 首部填入數(shù)值,每次經(jīng)過(guò)一個(gè)服務(wù)端就會(huì)-1,當(dāng)數(shù)字減少到0的時(shí)候,就會(huì)停止傳輸請(qǐng)求,直到接受到返回的狀態(tài)碼響應(yīng)才算結(jié)束。使用TRACE方法可以檢查當(dāng)前請(qǐng)求是否被篡改,但是由于當(dāng)前方法很容易引起XST(Cross-Site Tracing,跨站追蹤)攻擊,所以一般都禁止使用

CONNECT:要求用隧道協(xié)議連接代理

使用CONNECT方法要求是與代理服務(wù)器建立連接隧道,實(shí)現(xiàn)隧道間通信TCP,常見(jiàn)會(huì)使用SSL或者TLS協(xié)議把內(nèi)容加密后傳遞到隧道,CONNECT的格式如下:

CONNECT 代理服務(wù)器名:端口號(hào) HTTP版本

我們把1.0和1.1兩個(gè)版本的支持的協(xié)議方法列個(gè)表格,看下具體差異:

方法 作用 支持的協(xié)議版本
GET 獲取資源 1.0、1.1
POST 傳輸實(shí)體主體 1.0、1.1
PUT 傳輸文件 1.0、1.1
HEAD 獲得報(bào)文首部?jī)?nèi)容 1.0、1.1
DELETE 刪除文件 1.0、1.1
OPTIONS 獲取當(dāng)前URI支持的方法 1.1
TRACE 追蹤路徑 1.1
CONNECT 需要使用隧道協(xié)議連接代理 1.1
LINK 建立和資源之間的聯(lián)系 1.0
UNLINE 斷開(kāi)與資源的聯(lián)系 1.0

HTTP報(bào)文

HTTP通訊過(guò)程中用來(lái)交互傳輸數(shù)據(jù)的信息稱(chēng)之為報(bào)文,請(qǐng)求端發(fā)出的稱(chēng)之為請(qǐng)求報(bào)文,響應(yīng)端的稱(chēng)之為響應(yīng)報(bào)文,而HTTP的報(bào)文則是由多行字符串組合而成,其中回車(chē)符和換行符來(lái)區(qū)分每一個(gè)報(bào)文的內(nèi)容及其屬性以及報(bào)文首部和報(bào)文主體,報(bào)文整體組成大概如下:

報(bào)文組成.png

從上圖我們大概可以看出來(lái)報(bào)文整體通過(guò)空行拆分為報(bào)文首部和報(bào)文主體,并且請(qǐng)求報(bào)文和響應(yīng)報(bào)文都是一樣的結(jié)構(gòu),但是我們也可以看出來(lái),請(qǐng)求報(bào)文和響應(yīng)報(bào)文都包含通用首部字段和實(shí)體首部字段,而請(qǐng)求報(bào)文則是多了請(qǐng)求行和請(qǐng)求首部字段,響應(yīng)報(bào)文則是在相同位置變成了狀態(tài)行和響應(yīng)首部字段,那么這些組成分別有什么作用呢?

請(qǐng)求行

首先請(qǐng)求行僅僅存在于請(qǐng)求報(bào)文中,用來(lái)記錄當(dāng)前發(fā)起請(qǐng)求的信息,比如URI,請(qǐng)求方法,HTTP版本等

狀態(tài)行

狀態(tài)行僅僅存在于響應(yīng)報(bào)文中,內(nèi)部記錄了響應(yīng)結(jié)果的狀態(tài)碼,成功/失敗的原因說(shuō)明,以及服務(wù)端返回的HTTP版本等

請(qǐng)求首部/響應(yīng)首部/通用首部/實(shí)體首部

四種最常見(jiàn)的首部一般包含了請(qǐng)求/響應(yīng)過(guò)程中各種屬性及其對(duì)應(yīng)的參數(shù)值,比如跨域請(qǐng)求,緩存過(guò)期時(shí)間等屬性

其他首部

一般情況下HTTP內(nèi)置的首部和組成是由上面的四種常見(jiàn)首部和請(qǐng)求行/狀態(tài)行組成的,但是不要忘記,我們HTTP可以配合Cookie等實(shí)現(xiàn)功能,其他首部中包含了其他的非HTTP規(guī)范定義的首部信息比如Cookie首部信息等

HTTP首部

上面我們分析了報(bào)文的組成部分,其中有四個(gè)首部是最常見(jiàn)的首部,分別是請(qǐng)求首部、響應(yīng)首部、通用首部和實(shí)體首部,那么我們看下四種首部分別是用來(lái)做什么的,以及HTTP規(guī)范給我們定義了那些首部字段:

通用首部

所謂通用首部,即請(qǐng)求報(bào)文和響應(yīng)報(bào)文都可以配置的首部字段,一般都是超時(shí)時(shí)間、緩存等這些通用首部字段,HTTP規(guī)范定義的通用首部字段共9個(gè),如下:

首部字段 說(shuō)明
Cache-Control 緩存行為控制
Connection 跳轉(zhuǎn)首部、連接的管理
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ò)誤信息通知

請(qǐng)求首部字段

當(dāng)客戶(hù)端發(fā)起請(qǐng)求的時(shí)候特有的首部,可用來(lái)指定請(qǐng)求的方式,請(qǐng)求的策略等,HTTP定義的請(qǐng)求首部字段共19個(gè),如下:

首部字段 說(shuō)明
Accept 用戶(hù)代理可以處理的媒體類(lèi)型
Accept-Charset 優(yōu)先的編碼字符集
Accept-Encoding 優(yōu)先的內(nèi)容編碼
Accept-Language 優(yōu)先的語(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-Match 相反)
If-Range 資源未更新時(shí)發(fā)送實(shí)體 Byte 的范圍請(qǐng)求
If-Unmodified-Since 比較資源的更新時(shí)間(與If-Modified-Since相反)
Max-Forwards 最大傳輸逐跳數(shù)
Proxy-Authorization 代理服務(wù)器要求客戶(hù)端的認(rèn)證信息
Range 實(shí)體的字節(jié)范圍請(qǐng)求
Referer 對(duì)請(qǐng)求中 URI 的原始獲取方
TE 傳輸編碼優(yōu)先級(jí)
User-Agent HTTP 客戶(hù)端程序信息

響應(yīng)首部字段

HTTP交互過(guò)程中,服務(wù)端返回給客戶(hù)端的時(shí)候使用的首部,包含服務(wù)端信息、重定向等,在HTTP中定義的有9種,如下:

首部字段 說(shuō)明
Accept-Ranges 是否接受字節(jié)范圍請(qǐng)求
Age 推算資源創(chuàng)建經(jīng)過(guò)時(shí)間
ETag 資源的匹配信息
Location 令客戶(hù)端重定向至此URI
Proxy-Authenticate 代理服務(wù)器對(duì)客戶(hù)端的認(rèn)證信息
Retry-After 再次發(fā)起請(qǐng)求的時(shí)機(jī)要求信息
Server 服務(wù)器的安裝信息
Vary 代理服務(wù)器緩存的管理信息
WWW-Authenticate 服務(wù)器對(duì)客戶(hù)端的認(rèn)證信息

實(shí)體首部字段

實(shí)體首部字段是HTTP交互過(guò)程中,為了傳輸實(shí)體而出現(xiàn)的屬性配置,HTTP指定了10種實(shí)體首部,如下:

首部字段 說(shuō)明
Allow 當(dāng)前資源支持的請(qǐng)求方式
Content-Encoding 實(shí)體的編碼方式
Content-Language 實(shí)體對(duì)應(yīng)的語(yǔ)言
Content-Length 實(shí)體傳輸需要的byte大小
Content-Location 用來(lái)替代資源的URI
Content-MD5 實(shí)體的報(bào)文摘要
Content-Range 實(shí)體主體的傳輸位置范圍
Content-Type 實(shí)體主體的媒體類(lèi)型
Expires 實(shí)體主體過(guò)期時(shí)間
Last-Modified 資源的最后修改時(shí)間

而其中有部分首部在日常中經(jīng)常使用,下面我們就看看幾個(gè)常見(jiàn)的首部字段以及可選值:

Cache-Control:緩存行為控制

可用的值如下(請(qǐng)求):

屬性 參數(shù) 說(shuō)明
no-cache 強(qiáng)制要求服務(wù)端請(qǐng)求真實(shí)數(shù)據(jù)進(jìn)行返回
no-store 強(qiáng)制要求請(qǐng)求和響應(yīng)不做任何數(shù)據(jù)緩存
max-age 秒(必須) 可以保持響應(yīng)的最大時(shí)間
max-stale 接受已經(jīng)過(guò)期的響應(yīng)(xxx秒內(nèi)的響應(yīng))
min-fresh 秒(必須) 緩存過(guò)期,但是在指定時(shí)間內(nèi)客戶(hù)端依然認(rèn)可此數(shù)據(jù)
no-transform 代理不可更改媒體類(lèi)型
only-if-cached 僅僅選擇從緩存獲取數(shù)據(jù),沒(méi)有即504
cache-extension 從新標(biāo)記獲取數(shù)據(jù)(token)

可用的響應(yīng)值如下:

屬性 參數(shù) 說(shuō)明
public 公開(kāi)對(duì)任何客戶(hù)端都有效的緩存
private 僅針對(duì)指定客戶(hù)端緩存有效,彼此客戶(hù)端不干擾
no-cache 每次都確認(rèn)數(shù)據(jù)是否有效
no-store 請(qǐng)求或者響應(yīng)強(qiáng)制都不緩存數(shù)據(jù)
no-transform 代理不可更改媒體類(lèi)型
must-revalidate 可緩存但必須再向源服務(wù)器進(jìn)行確認(rèn)
proxy-revalidate 要求中間緩存服務(wù)器對(duì)緩存的響應(yīng)有效性再進(jìn)行確認(rèn)
max-age 秒(必須) 可以保持響應(yīng)的最大時(shí)間
s-maxage 秒(必須) 公共緩存服務(wù)器響應(yīng)的最大Age值
cache-extension 新指令標(biāo)記(token)

Warning:錯(cuò)誤信息通知

在HTTP1.1中定義的警告碼如下:

警告碼 警告內(nèi)容 說(shuō)明
110 Response is stale(響應(yīng)已過(guò)期) 代理返回已過(guò)期的資源
111 Revalidation failed(驗(yàn)證失?。?/td> 代理在驗(yàn)證資源有效性時(shí)失敗(服務(wù)器無(wú)法到達(dá))
112 Disconnection operation(斷開(kāi)連接操作) 代理與互聯(lián)網(wǎng)連接被故意切斷
113 Heuristic expiration(試探性過(guò)期) 響應(yīng)的使用期超過(guò)24小時(shí)(有效緩存時(shí)間在24h以上的情況)
199 Miscellaneous warning(雜項(xiàng)警告) 任意的警告
214 Transformation applied(使用了轉(zhuǎn)換) 代理對(duì)內(nèi)容編碼或媒體類(lèi)型等執(zhí)行了轉(zhuǎn)換等操作
299 Miscellaneous persistent warning(持久雜項(xiàng)警告) 任意的警告

Accept:用戶(hù)代理可以處理的媒體類(lèi)型

Accept屬性可以通知服務(wù)器,用戶(hù)代理能接受/處理的媒體文件類(lèi)型以及優(yōu)先級(jí),常見(jiàn)的如下:

媒體文件類(lèi)型 可選值(部分)
文本文件 text/html, text/plain, text/css,application/xhtml+xml, application/xml
圖片文件 image/jpeg, image/gif, image/png
視頻文件 video/mpeg, video/quicktime
二進(jìn)制文件 application/octet-stream, application/zip

其中Accept還可以指定優(yōu)先級(jí),使用q=來(lái)額外表示權(quán)重值,用分號(hào)分割,權(quán)重范圍0-1,1為最大值,可以為三位小數(shù),不指定權(quán)重時(shí)默認(rèn)q=1.0

Accept-Encoding:優(yōu)先的內(nèi)容編碼

Accept-Encoding用來(lái)通知服務(wù)器用戶(hù)代理支持的內(nèi)容編碼及優(yōu)先級(jí)順序,常見(jiàn)的編碼如下:

編碼類(lèi)型 說(shuō)明
gzip 傳輸數(shù)據(jù)由文本壓縮程序gzip生成對(duì)應(yīng)編碼數(shù)據(jù)
compress 由 UNIX 文件壓縮程序 compress 生成的編碼格式,采用 Lempel-Ziv-Welch 算法(LZW)
deflate 組合使用 zlib 格式(RFC1950)及由 deflate 壓縮算法生成的編碼
identity 不執(zhí)行任何壓縮等操作的默認(rèn)編碼

HTTP狀態(tài)碼

了解了HTTP的報(bào)文組成和組成HTTP請(qǐng)求/響應(yīng)的首部信息,在完成了HTTP請(qǐng)求后,我們會(huì)根據(jù)響應(yīng)報(bào)文來(lái)確定用戶(hù)操作是否規(guī)范,而依據(jù)則是響應(yīng)報(bào)文中很重要的一部分--HTTP狀態(tài)碼

而在HTTP規(guī)范中,響應(yīng)碼以三位數(shù)的短數(shù)值和簡(jiǎn)要的信息表示,而三位數(shù)值的第一位數(shù)(百位數(shù))決定了響應(yīng)的類(lèi)型,后兩位數(shù)則是當(dāng)前類(lèi)型的具體子類(lèi)型,目前HTTP中的code主要分為以下五種:

響應(yīng)code 類(lèi)型 響應(yīng)原因短語(yǔ)
1XX Informational(信息性狀態(tài)碼) 接收的請(qǐng)求正在處理
2XX Success(成功狀態(tài)碼) 請(qǐng)求正常處理完畢
3XX Redirection(重定向狀態(tài)碼) 需要進(jìn)行附加操作以完成請(qǐng)求
4XX Client Error(客戶(hù)端錯(cuò)誤狀態(tài)碼) 服務(wù)器無(wú)法處理請(qǐng)求
5XX Server Error(服務(wù)器錯(cuò)誤狀態(tài)碼) 服務(wù)器處理請(qǐng)求出錯(cuò)

而這五大類(lèi)型的具體子類(lèi)在RFC2616 上的 HTTP 狀態(tài)碼就達(dá) 40 種,后續(xù)擴(kuò)展了數(shù)十種,而在我們開(kāi)發(fā)過(guò)程中,絕大多數(shù)幾乎見(jiàn)不到,所以接下來(lái)我們看看開(kāi)發(fā)中能碰到的十來(lái)種常見(jiàn)的狀態(tài)碼

200:完全成功

當(dāng)HTTP的返回碼為200的時(shí)候,恭喜你,整個(gè)流程沒(méi)有出現(xiàn)任何問(wèn)題,完全成功!說(shuō)明客戶(hù)端的請(qǐng)求信息被服務(wù)端正常處理并且成功返回給了客戶(hù)端

204:Not Content

當(dāng)前的狀態(tài)碼代表客戶(hù)端的請(qǐng)求已經(jīng)被服務(wù)端處理完畢,并且服務(wù)端也給了響應(yīng)信息,但是當(dāng)前的返回信息中不包含響應(yīng)信息主體

206:Partial Content

當(dāng)前返回碼比較特殊,因?yàn)橹粫?huì)出現(xiàn)在客戶(hù)端的請(qǐng)求是部分范圍請(qǐng)求并且成功響應(yīng)的時(shí)候,比如報(bào)文中包含 Content-Range 進(jìn)行部分范圍請(qǐng)求的操作

301:Moved Permanently

當(dāng)前響應(yīng)碼代表著請(qǐng)求的資源已經(jīng)被永久性重定向,即我們請(qǐng)求的資源在服務(wù)端的URI已經(jīng)變更,服務(wù)端期望我們使用Loaction首部字段等方式保存新的URI地址,后續(xù)使用當(dāng)前URI進(jìn)行訪問(wèn)

302:Found

當(dāng)前響應(yīng)碼和301有類(lèi)似的地方,即都是請(qǐng)求資源被重定向了,但是區(qū)別在于301是請(qǐng)求的資源URI的永久性移動(dòng)變更,而302響應(yīng)碼代表著當(dāng)前請(qǐng)求的時(shí)候這個(gè)資源的URI被變更了,但是這個(gè)變更只是臨時(shí)的,僅僅本次請(qǐng)求期望使用變更后的URI請(qǐng)求

303:See Other

如果是302響應(yīng)碼是臨時(shí)性URI變更的話,那么303就是302的升級(jí)版,因?yàn)?03響應(yīng)碼擁有302響應(yīng)碼的全部功能,但是更嚴(yán)格的是,303告訴你URI對(duì)應(yīng)的資源中存在其他URI,并且嚴(yán)格要求你使用GET方式去重新訪問(wèn)新的URI

307:Temporary Redirect

303作為302的升級(jí)版已經(jīng)出現(xiàn)了,但是在嚴(yán)格程度上還遠(yuǎn)遠(yuǎn)不夠,因?yàn)榘凑誋TTP規(guī)范,302,303的響應(yīng)碼都是希望用戶(hù)不要把POST請(qǐng)求變?yōu)镚ET,但是不能束縛瀏覽器或者用戶(hù)行為,而307作為嚴(yán)格的執(zhí)行者,只要響應(yīng)了當(dāng)前的code,瀏覽器會(huì)遵照約定,不能把POST請(qǐng)求變成GET去訪問(wèn)資源

400:Bad Request

400響應(yīng)碼可能是最詭異的響應(yīng)碼之一了,開(kāi)發(fā)的過(guò)程中需要格外注意當(dāng)前的響應(yīng)碼,因?yàn)楫?dāng)前響應(yīng)碼雖然是告訴我們報(bào)文請(qǐng)求中存在著語(yǔ)法錯(cuò)誤,但是瀏覽器會(huì)按照200對(duì)待此響應(yīng)

401:Unauthorized

當(dāng)響應(yīng)401響應(yīng)碼的時(shí)候,即代表服務(wù)端會(huì)發(fā)起質(zhì)詢(xún)的方式的一個(gè)認(rèn)證請(qǐng)求,告訴我們需要進(jìn)行認(rèn)證才可以訪問(wèn),這個(gè)時(shí)候我們需要將信息填寫(xiě)并確定才可以拿到具體的結(jié)果

403:Forbidden

403響應(yīng)碼在開(kāi)發(fā)的時(shí)候也是經(jīng)常出現(xiàn),經(jīng)常讓人琢磨不透原因,因?yàn)榇隧憫?yīng)碼出現(xiàn)即代表我們的請(qǐng)求被服務(wù)端拒絕訪問(wèn)了,但是服務(wù)端經(jīng)常不會(huì)返回給具體的響應(yīng)實(shí)體描述

404:Not Found

404作為開(kāi)發(fā)過(guò)程中接觸最多的響應(yīng)碼之一,對(duì)此已經(jīng)非常熟悉,此響應(yīng)碼代表服務(wù)端無(wú)法找到具體的請(qǐng)求資源

501:Internal Server Error

501狀態(tài)碼表明當(dāng)前服務(wù)端在執(zhí)行過(guò)程中發(fā)生了錯(cuò)誤,也可能是某個(gè)流程突發(fā)bug

503:Service Unavailable

503狀態(tài)碼代表我們請(qǐng)求服務(wù)端的過(guò)程中,服務(wù)端可能超過(guò)了負(fù)載或者服務(wù)端的機(jī)器已經(jīng)宕機(jī)又或者正在停服更新?tīng)顟B(tài)等

BASIC 認(rèn)證

上面有分析開(kāi)發(fā)和日常使用過(guò)程中最常見(jiàn)的十?dāng)?shù)種響應(yīng)碼及其含義,其中401是代表我們需要經(jīng)過(guò)認(rèn)證,那么接下來(lái)我們了解下HTTP協(xié)議給我們提供的幾種認(rèn)證方式吧,其中HTTP1.1版本默認(rèn)支持的認(rèn)證方式有如下:

BASIC:基礎(chǔ)認(rèn)證、DIGEST:信息摘要認(rèn)證、SSL:基于ssl協(xié)議的客戶(hù)端認(rèn)證、FormBase:基于表單的認(rèn)證方式

那么我們從BASIC認(rèn)證開(kāi)始,此認(rèn)證是HTTP1.0就開(kāi)始存在的認(rèn)證方式,比較古老,現(xiàn)在的web開(kāi)發(fā)過(guò)程中基本已經(jīng)不使用此方式,但是一些古老的工程依然存在(比如我之前的某企業(yè)的工程),其認(rèn)證過(guò)程大概如下:

1).發(fā)起請(qǐng)求,服務(wù)端返回401,并且返回帶 WWW-Authenticate 首部字段的響應(yīng)

2).客戶(hù)端接受到401響應(yīng)后,將用戶(hù)ID和密碼直接明文方式填寫(xiě),而發(fā)送的字符串會(huì)以id:密碼進(jìn)行組合后,經(jīng)過(guò)base64編碼為字符串發(fā)送


Basic認(rèn)證.png

需要注意的是此認(rèn)證方式弊端很多,首先是明文填寫(xiě),發(fā)送的過(guò)程中也沒(méi)有加密,僅僅是組合+base64進(jìn)行編碼,最重要的是此認(rèn)證方式基本上沒(méi)有注銷(xiāo)的選項(xiàng),所以基本沒(méi)人使用了

DIGEST 認(rèn)證

為彌補(bǔ) BASIC 認(rèn)證存在的弱點(diǎn),從 HTTP/1.1 起就有了 DIGEST 認(rèn) 證。DIGEST 認(rèn)證同樣使用質(zhì)詢(xún) / 響應(yīng)的方式 ,但是不會(huì)和BASIC一樣直接發(fā)送明文密碼,請(qǐng)求過(guò)程如下:

1).發(fā)送請(qǐng)求,服務(wù)端返回401,并且返 回帶 WWW-Authenticate 首部字段的響應(yīng) ,此字段中包含響應(yīng)方式對(duì)應(yīng)的質(zhì)詢(xún)碼(首部字段 WWW-Authenticate 內(nèi)必須包含 realm 和 nonce 這兩個(gè)字段的 信息。客戶(hù)端就是依靠向服務(wù)器回送這兩個(gè)值進(jìn)行認(rèn)證的)

2).此時(shí)客戶(hù)端接受到401的響應(yīng)以后,可以拿到DIGEST認(rèn)證需要的相關(guān)信息,比如realm和nonce,而完成此認(rèn)證還需要username和uri,這部分內(nèi)容填寫(xiě)完畢后開(kāi)始進(jìn)行計(jì)算發(fā)送給服務(wù)端(這部分進(jìn)行了加密計(jì)算,比較復(fù)雜,可以參考 RFC2617 )

3).接受到到包含首部字段 Authorization 請(qǐng)求的服務(wù)器,會(huì)確認(rèn)認(rèn) 證信息的正確性。認(rèn)證通過(guò)后則返回包含 Request-URI 資源的響應(yīng)

digest認(rèn)證.png

但是需要注意的是,此認(rèn)證雖然改善了basic認(rèn)證的明文問(wèn)題,但是不能防止客戶(hù)端被攻擊或者偽造的情況,使用起來(lái)也不能定制化,所以和basic一樣,很少有人使用

SSL 客戶(hù)端認(rèn)證

SLL認(rèn)證是借助HTTPS的客戶(hù)端證書(shū)完成用戶(hù)身份認(rèn)證,服務(wù)端也可以確認(rèn)當(dāng)前請(qǐng)求的客戶(hù)端是不是符合規(guī)范的客戶(hù)端,此種方式一般都是選擇HTTPS,是目前主流的安全的認(rèn)證方式之一,認(rèn)證步驟大概如下:

1).接受到客戶(hù)端的請(qǐng)求后,服務(wù)端發(fā)送送 Certificate Request 報(bào)文,要求客戶(hù)端提供客戶(hù)端證書(shū)

2).用戶(hù)在客戶(hù)端選擇證書(shū),客戶(hù)端會(huì)把證書(shū)信息發(fā)送給服務(wù)端

3).服務(wù)端會(huì)對(duì)證書(shū)進(jìn)行驗(yàn)證簽名等操作確定客戶(hù)端證書(shū)的有效性,通過(guò)后會(huì)按照證書(shū)內(nèi)部的公開(kāi)密鑰開(kāi)始進(jìn)行HTTPS通信

表單認(rèn)證

HTTPS雖然是能保證相對(duì)的安全性,但是在使用和操作上繁瑣,并且更重要的一點(diǎn)是,證書(shū)是要錢(qián)的,在企業(yè)開(kāi)發(fā)中,一般只會(huì)給比較私密的接口或者服務(wù)比如交易等進(jìn)行HTTPS通信,其他部分基本也不會(huì)選擇HTTPS,這個(gè)時(shí)候就需要一種自定義的安全擴(kuò)展認(rèn)證方式,而HTTP給我們提供了表單認(rèn)證,也是目前互聯(lián)網(wǎng)企業(yè)使用最多的方式

使用表單認(rèn)證基本是企業(yè)內(nèi)部自己開(kāi)發(fā)和定義具體的認(rèn)證響應(yīng)流程,而具體使用僅僅是在網(wǎng)頁(yè)提供表單填寫(xiě)相關(guān)信息,提交給服務(wù)端,服務(wù)端根據(jù)自定義的規(guī)則解析或者解密并響應(yīng),此種方式主要在于靈活,比如表單填寫(xiě)的信息可任意,文本形式可以任意,而請(qǐng)求過(guò)程可以自定義也可以選擇表單的submit提交,服務(wù)端靈活度更高,是目前主流并且推薦的認(rèn)證方式

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

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

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