HTTP請求報文與響應(yīng)報文格式
請求報文包含四部分:
a俱尼、請求行:包含請求方法册招、URI岔激、HTTP版本信息 b、請求首部字段 c是掰、請求內(nèi)容實體 d虑鼎、空行
響應(yīng)報文包含四部分:
a、狀態(tài)行:包含HTTP版本键痛、狀態(tài)碼炫彩、狀態(tài)碼的原因短語 b、響應(yīng)首部字段 c絮短、響應(yīng)內(nèi)容實體 d江兢、空行
一. 請求報文
二. 響應(yīng)報文
三. HTTP1.1下4種首部字段
1. 請求首部字段
字段名 | 描述 |
---|---|
Accept | 用戶代理可處理的媒體類型 |
Accept-Charset | 優(yōu)先的字符集 |
Accept-Encoding | 優(yōu)先的內(nèi)容編碼 |
Accept-Language | 優(yōu)先的語言 |
Authorization | Web認證信息 |
Proxy-Authorization | 代理服務(wù)器要求的認證信息 |
Expect | 期待服務(wù)器的特定行為 |
From | 用戶的電子郵箱地址 |
Host | 請求資源所在服務(wù)器 |
Referer | 對請求中 URI 的原始獲取方 |
If-Match | 比較實體標記(ETag) |
If-None-Match | 與 If-Match 相反 |
If-Modified-Since | 比較資源的更新時間 |
If-Unmodified-Since | 與If-Modified-Since相反 |
If-Range | 資源未更新時發(fā)送實體 Byte 的范圍請求 |
Range | 實體的字節(jié)范圍請求 |
Max-Forwards | 最大傳輸逐跳數(shù) |
TE | 傳輸編碼的優(yōu)先級 |
User-Agent | HTTP 客戶端程序的信息 |
2. 響應(yīng)首部字段
字段名 | 描述 |
---|---|
Accept-Ranges | 是否接受字節(jié)范圍請求 |
Age | 推算資源創(chuàng)建經(jīng)過時間 |
ETag | 資源標志 |
Location | 令客戶端重定向至指定URI |
Proxy-Authenticate | 代理服務(wù)器對客戶端的認證信息 |
Retry-After | 對再次發(fā)起請求的時機要求 |
Server | HTTP服務(wù)器的安裝信息 |
Vary | 代理服務(wù)器緩存的管理信息 |
WWW-Authenticate | 服務(wù)器對客戶端的認證信息 |
3. 通用首部字段
字段名 | 描述 |
---|---|
Cache-Control | 控制緩存 |
Connection | 逐跳首部、連接的管理 |
Date | 創(chuàng)建報文的日期時間 |
Pragma | 報文指令 |
Trailer | 報文末端的首部一覽 |
Transfer-Encoding | 指定報文主體的傳輸編碼方式 |
Upgrade | 升級為其他協(xié)議 |
Via | 代理服務(wù)器的相關(guān)信息 |
Warning | 錯誤通知 |
4. 實體首部字段
字段名 | 描述 |
---|---|
Allow | 支持的HTTP方法 |
Content-Encoding | 實體主體適用的編碼方式 |
Content-Language | 實體主體的自然語言 |
Content-Length | 實體主體的大衅萃琛(單位:字節(jié)) |
Content-Location | 替代對應(yīng)資源的URI |
Content-MD5 | 實體主體的報文摘要 |
Content-Range | 實體主體的位置范圍 |
Content-Type | 實體主體的媒體類型 |
Expires | 資源有效時間 |
Last-Modified | 資源的最后修改日期時間 |
5. 其他字段(非HTTP1.1定義)
字段名 | 描述 |
---|---|
Cookie | 請求首部 |
Set-Cookie | 響應(yīng)首部 |
Access-Control-Allow-Origin | 響應(yīng)首部 |
Access-Control-Allow-Headers | 響應(yīng)首部 |
Access-Control-Allow-Methods | 響應(yīng)首部 |
一划址、HTTP協(xié)議的主要特點
- 簡單快速:每個資源URI都是固定的
- 靈活:頭部有數(shù)據(jù)類型,可以完成不同類型傳輸
- 無連接:傳輸完成即斷開
- 無狀態(tài):建立連接 完成傳輸 下一次客戶端傳輸 是不知道兩次連接者的身份的
- 應(yīng)用層協(xié)議
其他協(xié)議:SOAP是一種簡單基于XML的輕量協(xié)議
二限府、HTTP報文的組成部分
- 請求報文
- 請求行(首行):HTTP方法夺颤、頁面地址(/表示首頁)、HTTP協(xié)議/版本
- 請求頭:HTTP協(xié)議告訴服務(wù)端要哪些內(nèi)容(key/value值)
- 空行:告訴服務(wù)端胁勺,請求頭部分結(jié)束
- 請求體
- 響應(yīng)報文
- 狀態(tài)行:HTTP協(xié)議世澜、狀態(tài)碼
- 響應(yīng)頭
- 空行
- 響應(yīng)體
2.1 瀏覽器輸入一個url后關(guān)于HTTP請求發(fā)生了什么
2.3 數(shù)據(jù)協(xié)商 - HTTP請求頭
Header | 解釋 | 示例 |
---|---|---|
Accept | 指定客戶端能夠接收的內(nèi)容類型 | Accept: text/plain, text/html |
Accept-Charset | 瀏覽器可以接受的字符編碼集。 | Accept-Charset: iso-8859-5 |
Accept-Encoding | 指定瀏覽器可以支持的web服務(wù)器返回數(shù)據(jù)壓縮編碼類型署穗。 | Accept-Encoding: compress, gzip |
Accept-Language | 瀏覽器可接受的語言 | Accept-Language: en,zh |
Accept-Ranges | 可以請求網(wǎng)頁實體的一個或者多個子范圍字段 | Accept-Ranges: bytes |
Authorization | HTTP授權(quán)的授權(quán)證書 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定請求和響應(yīng)遵循的緩存機制 | Cache-Control: no-cache |
Connection | 表示是否需要持久連接寥裂。(HTTP 1.1默認進行持久連接) | Connection: keep-alive |
Cookie | HTTP請求發(fā)送時嵌洼,會把保存在該請求域名下的所有cookie值一起發(fā)送給web服務(wù)器。 | Cookie: $Version=1; Skin=new; |
Content-Length | 請求的內(nèi)容長度 | Content-Length: 348 |
Content-Type | 請求的與實體對應(yīng)的MIME信息 | Content-Type: application/x-www-form-urlencoded |
Date | 請求發(fā)送的日期和時間 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expect | 請求的特定的服務(wù)器行為 | Expect: 100-continue |
From | 發(fā)出請求的用戶的Email | From: user@email.com |
Host | 指定請求的服務(wù)器的域名和端口號 | Host: www.baidu.com |
If-Match | 只有請求內(nèi)容與實體相匹配才有效 | If-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Modified-Since | 如果請求的部分在指定時間之后被修改則請求成功封恰,未被修改則返回304代碼 | If-Modified-Since: Wed, 31 Oct 2018 05:10:43 GMT |
If-None-Match | 如果內(nèi)容未改變返回304代碼麻养,參數(shù)為服務(wù)器先前發(fā)送的Etag,與服務(wù)器回應(yīng)的Etag比較判斷是否改變 | If-None-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Range | 如果實體未改變诺舔,服務(wù)器發(fā)送客戶端丟失的部分鳖昌,否則發(fā)送整個實體。參數(shù)也為Etag | If-Range: “737060cd8c284d8af7ad3082f209582d” |
If-Unmodified-Since | 只在實體在指定時間之后未被修改才請求成功 | If-Unmodified-Since: Wed, 31 Oct 2018 05:10:43 GMT |
Max-Forwards | 限制信息通過代理和網(wǎng)關(guān)傳送的時間 | Max-Forwards: 10 |
Pragma | 用來包含實現(xiàn)特定的指令 | Pragma: no-cache |
Proxy-Authorization | 連接到代理的授權(quán)證書 | Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range | 只請求實體的一部分低飒,指定范圍 | Range: bytes=500-999 |
Referer | 先前網(wǎng)頁的地址许昨,當(dāng)前請求網(wǎng)頁緊隨其后,即來路 | Referer: https://www.baidu.com/ |
TE | 客戶端愿意接受的傳輸編碼,并通知服務(wù)器接受接受尾加頭信息 | TE: trailers,deflate;q=0.5 |
Upgrade | 向服務(wù)器指定某種傳輸協(xié)議以便服務(wù)器進行轉(zhuǎn)換(如果支持) | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agent | User-Agent的內(nèi)容包含發(fā)出請求的用戶信息(判斷返回PC端的頁面還是移動端的頁面) | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 |
Via | 通知中間網(wǎng)關(guān)或代理服務(wù)器地址褥赊,通信協(xié)議 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 關(guān)于消息實體的警告信息 | Warn: 199 Miscellaneous warning |
2.4 數(shù)據(jù)協(xié)商 - HTTP響應(yīng)頭
Header | 解釋 | 示例 |
---|---|---|
Accept-Ranges | 表明服務(wù)器是否支持指定范圍請求及哪種類型的分段請求 | Accept-Ranges: bytes |
Age | 從原始服務(wù)器到代理緩存形成的估算時間(以秒計糕档,非負) | Age: 12 |
Allow | 對某網(wǎng)絡(luò)資源的有效的請求行為,不允許則返回405 | Allow: GET, HEAD |
Cache-Control | 告訴所有的緩存機制是否可以緩存及哪種類型 | Cache-Control: private |
Content-Encoding | web服務(wù)器支持的返回內(nèi)容壓縮編碼類型拌喉。 | Content-Encoding: gzip |
Content-Language | 響應(yīng)體的語言 | Content-Language: en,zh |
Content-Length | 響應(yīng)體的長度 | Content-Length: 348 |
Content-MD5 | 返回資源的MD5校驗值 | Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ== |
Content-Range | 在整個返回體中本部分的字節(jié)位置 | Content-Range: bytes 21010-47021/47022 |
Content-Type | 返回內(nèi)容的MIME類型 | Content-Type: application/x-www-form-urlencoded; charset=utf-8 |
Date | 原始服務(wù)器消息發(fā)出的時間 | Date: Wed, 31 Oct 2018 05:10:43 GMT |
etag | 請求變量的實體標簽的當(dāng)前值 | etag: W/"847a3c5130b6c83cd331dee376e0d0a3" |
Expires | 響應(yīng)過期的日期和時間 | Expires: Wed, 31 Oct 2018 05:10:43 GMT |
Last-Modified | 請求資源的最后修改時間 | Last-Modified: Wed, 31 Oct 2018 05:10:43 GMT |
Location | 用來重定向接收方到非請求URL的位置來完成請求或標識新的資源(301/302) | Location: https://www.hao123.com/ |
Pragma | 包括實現(xiàn)特定的指令速那,它可應(yīng)用到響應(yīng)鏈上的任何接收方 | Pragma: no-cache |
Proxy-Authenticate | 它指出認證方案和可應(yīng)用到代理的該URL上的參數(shù) | Proxy-Authenticate: Basic |
refresh | 應(yīng)用于重定向或一個新的資源被創(chuàng)造,在5秒之后重定向(由網(wǎng)景提出尿背,被大部分瀏覽器支持) | Refresh: 5; url=https://www.hao123.com/ |
Retry-After | 如果實體暫時不可取琅坡,通知客戶端在指定時間之后再次嘗試 | Retry-After: 120 |
Server | web服務(wù)器軟件名稱 | Server: BWS/1.0 |
Set-Cookie | 設(shè)置Http Cookie | Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 |
Trailer | 指出頭域在分塊傳輸編碼的尾部存在 | Trailer: Max-Forwards |
Transfer-Encoding | 文件傳輸編碼 | Transfer-Encoding:chunked |
Vary | 告訴下游代理是使用緩存響應(yīng)還是從原始服務(wù)器請求 | Vary: * |
Via | 告知代理客戶端響應(yīng)是通過哪里發(fā)送的 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 警告實體可能存在的問題 | Warning: 199 Miscellaneous warning |
WWW-Authenticate | 表明客戶端請求實體應(yīng)該使用的授權(quán)方案 | WWW-Authenticate: Basic |
三、HTTP協(xié)議的發(fā)展歷史
HTTP/0.9:
- 只有一個命令GET
- 沒有 header 等描述數(shù)據(jù)的信息
- 服務(wù)器發(fā)送完畢残家,就關(guān)閉TCP連接
HTTP/1.0:
- 增加了很多命令
- 增加了status code 和 header
- 多字符集支持、多部分發(fā)送售躁、權(quán)限和緩存等
HTTP/1.1:
- 持久連接
- pipeline
- 增加 host (可以在一個集群上同時跑多個web服務(wù)坞淮,通過host字段來判斷使用node還是Java服務(wù),提高物理服務(wù)的使用效率)和其他一些命令
HTTP/2.0:
- 分幀傳輸:所有數(shù)據(jù)以二進制(幀)傳輸陪捷,之前都是用字符串
- 多路復(fù)用(信道復(fù)用):同一個連接中發(fā)送多個請求回窘,不再需要按照順序來
- 頭信息壓縮(之前都是完整發(fā)送和返回,占用帶寬的量比較大)以及推送(支持server push市袖,即服務(wù)端可以主動發(fā)送數(shù)據(jù)傳輸)等提高效率的功能
場景:web頁面有html啡直、css等文件,有根據(jù)請求的url才能解析出html等文件的路徑苍碟。這里就會包含執(zhí)行順序的問題酒觅,使用HTTP/2.0之前的協(xié)議首先要先請求、解析之后才能獲取html微峰、css舷丹、js,而且瀏覽器的并發(fā)請求數(shù)目是一定的蜓肆,即對同一域名下的請求有一定數(shù)量限制(一般為6-10個)颜凯,超過限制數(shù)目的請求會被阻塞谋币。而HTTP/2.0 中只創(chuàng)建一個HTTP連接,數(shù)據(jù)傳輸和請求的發(fā)送是并行的症概,會改善效率蕾额、減少握手開銷。
四彼城、TCP 三次握手和四次揮手
4.1 三次握手
類比:
客戶:在嗎诅蝶?我想跟你聊天。(發(fā)送SYN請求同步報文)
服務(wù):好的精肃,我聽著呢秤涩。(發(fā)送SYN請求同步報文,確認同步)你說吧司抱。(發(fā)送ACK確認報文筐眷,即可以開始吐槽了)
客戶:好的。(發(fā)送ACK確認報文)今天...(開始吐槽)
圖例:
-
第一次握手(SYN=1, seq=J):
客戶端發(fā)送一個 TCP 的 SYN 標志位置1的包习柠,指明客戶端打算連接的服務(wù)器的端口匀谣,以及初始序號 J,保存在包頭的序列號(Sequence Number)字段里资溃。
發(fā)送完畢后武翎,客戶端進入
SYN_SEND
狀態(tài)。 -
第二次握手(SYN=1, ACK=1, seq=K, ACKnum=J+1):
服務(wù)器發(fā)回確認包(ACK)應(yīng)答溶锭。即 SYN 標志位和 ACK 標志位均為1宝恶。服務(wù)器端選擇自己 ISN 序列號,放到 Seq 域里趴捅,同時將確認序號(Acknowledgement Number)設(shè)置為客戶的 ISN 加1垫毙,即J+1。 發(fā)送完畢后拱绑,服務(wù)器端進入
SYN_RCVD
狀態(tài)综芥。 -
第三次握手(ACK=1,ACKnum=K+1)
客戶端再次發(fā)送確認包(ACK)猎拨,SYN 標志位為0膀藐,ACK 標志位為1,并且把服務(wù)器發(fā)來 ACK 的序號字段+1红省,放在確定字段中發(fā)送給對方额各,并且在數(shù)據(jù)段放寫ISN的+1
發(fā)送完畢后,客戶端進入
ESTABLISHED
狀態(tài)类腮,當(dāng)服務(wù)器端接收到這個包時臊泰,也進入ESTABLISHED
狀態(tài),TCP 握手結(jié)束。
為什么要三次握手:防止無用連接缸逃,規(guī)避網(wǎng)絡(luò)延遲等原因造成的網(wǎng)絡(luò)開銷浪費的問題针饥。
4.2 四次揮手
類比:
客戶:我有事兒要掛電話了。(發(fā)送FIN結(jié)束報文需频,1次揮手)
服務(wù):好吧(發(fā)送ACK確認報文丁眼,2次揮手),對了昭殉,還有個事兒要跟你說苞七。
......
服務(wù):說完了,掛了吧挪丢。(發(fā)送FIN結(jié)束報文蹂风,3次揮手)
客戶:好的,拜拜乾蓬。(發(fā)送ACK確認報文惠啄,4次揮手)
服務(wù)掛斷電話.....
2MSL后......
客戶:我知道了。
啪H文凇(這才斷開連接)
圖例:
- 第一次揮手(FIN=1撵渡,seq=M)
? 假設(shè)客戶端想要關(guān)閉連接,客戶端發(fā)送一個 FIN 標志位置為1的包死嗦,表示自己已經(jīng)沒有數(shù)據(jù)可以發(fā)送了趋距,但是仍然可以接受數(shù)據(jù)。發(fā)送完畢后越除,客戶端進入 FIN_WAIT_1
狀態(tài)节腐。
- 第二次揮手(ACK=1,ACKnum=M+1)
? 服務(wù)器端確認客戶端的 FIN 包摘盆,發(fā)送一個確認包铜跑,表明自己接受到了客戶端關(guān)閉連接的請求,但還沒有準備好關(guān)閉連接骡澈。發(fā)送完畢后,服務(wù)器端進入 CLOSE_WAIT
狀態(tài)掷空,客戶端接收到這個確認包之后肋殴,進入 FIN_WAIT_2
狀態(tài),等待服務(wù)器端關(guān)閉連接坦弟。
- 第三次揮手(FIN=1护锤,seq=K)
? 服務(wù)器端準備好關(guān)閉連接時,向客戶端發(fā)送結(jié)束連接請求酿傍,F(xiàn)IN 置為1烙懦。發(fā)送完畢后,服務(wù)器端進入 LAST_ACK
狀態(tài)赤炒,等待來自客戶端的最后一個ACK氯析。
- 第四次揮手(ACK=1亏较,ACKnum=K+1)
? 客戶端接收到來自服務(wù)器端的關(guān)閉請求,發(fā)送一個確認包掩缓,并進入 TIME_WAIT
狀態(tài)雪情,等待可能出現(xiàn)的要求重傳的 ACK 包。服務(wù)器端接收到這個確認包之后你辣,關(guān)閉連接巡通,進入 CLOSED
狀態(tài)∩岷澹客戶端等待了某個固定時間(兩個最大段生命周期宴凉,2MSL,2 Maximum Segment Lifetime)之后表悬,沒有收到服務(wù)器端的 ACK 弥锄,認為服務(wù)器端已經(jīng)正常關(guān)閉連接,于是自己也關(guān)閉連接签孔,進入 CLOSED
狀態(tài)叉讥。
五、TCP饥追、UDP對比
TCP | UDP | |
---|---|---|
可靠性 | 可靠 | 不可靠 |
連接性 | 面向連接 | 無連接 |
報文 | 面向字節(jié)流 | 面向報文 |
效率 | 傳輸效率低 | 傳輸效率高 |
雙工性 | 全雙工 | 一對一图仓、一對多、多對一但绕、多對多 |
流量控制 | 有(滑動窗口) | 無 |
擁塞控制 | 有(慢開始救崔、擁塞避免、快重傳捏顺、快恢復(fù)) | 無 |
六六孵、HTTP方法
HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法励幼。
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法立由。
HTTP方法名 | 作用 |
---|---|
GET | 獲取資源 |
POST | 傳輸資源 |
PUT | 更新/修改資源 |
DELETE | 刪除資源 |
HEAD | 獲得報文首部 |
CONNECT | HTTP/1.1協(xié)議中預(yù)留給能夠?qū)⑦B接改為管道方式的代理服務(wù)器 |
OPTIONS | 返回服務(wù)器針對特定資源所支持的HTTP請求方法挑秉,允許客戶端發(fā)送'*' 查看服務(wù)器的性能 |
TRACE | 回顯服務(wù)器收到的請求拿撩,主要用于測試或診斷 |
推薦:同一個url通過不同的方法來實現(xiàn)肌访,設(shè)計符合RESTful風(fēng)格的接口芭梯。
七您市、POST和GET區(qū)別
場景 | GET | POST |
---|---|---|
瀏覽器回退 | 無害的 | 會重復(fù)提交請求 |
產(chǎn)生的URL地址 | 可以被收藏 | 不可以 |
瀏覽器緩存 | 主動緩存 | 不會自動緩存碱蒙,除非手動設(shè)置 |
編碼方式 | 只能進行URL編碼 | 支持多種編碼方式 |
瀏覽器歷史記錄中的請求參數(shù) | 完整保留 | 不會保留 |
URL中傳遞的參數(shù)長度 | 2KB左右挪凑,不同瀏覽器限制不同孕索。故參數(shù)不要太長,容易被瀏覽器截斷躏碳。 | 沒有限制 |
參數(shù)的數(shù)據(jù)類型 | ASCII字符 | 沒有限制 |
安全性 | 參數(shù)直接暴露在URL上搞旭,還可能造成CSRF攻擊(以?分割URL和傳輸數(shù)據(jù),多個參數(shù)用&連接) | 可以傳遞敏感信息 |
參數(shù)傳遞 | URL傳遞 | Request body中 |
八、HTTP CODE
一個好的HTTP服務(wù)可以通過CODE判斷結(jié)果
1XX:指示信息 - 表示請求已接收肄渗,繼續(xù)處理
2XX:成功 - 表示請求已被成功接收
- 200 OK:客戶端請求成功
- 201 Created:請求成功并且服務(wù)器創(chuàng)建了新的資源
- 202 Accepted:服務(wù)器已接受請求镇眷,但尚未處理
- 206 Partial Content:客戶端發(fā)送了一個帶有Range頭的GET請求,服務(wù)器完成了它
場景:video播放視頻地址/audio播放音頻地址恳啥,如果文件過大偏灿,則一般會返回206
3XX:重定向 - 要完成請求必須進行更進一步的操作
- 301 Moved Permanently:所請求的頁面已經(jīng)永久轉(zhuǎn)移至新的URL(永久重定向)
- 302 Found:所請求的頁面已經(jīng)臨時轉(zhuǎn)移至新的URL(臨時重定向)
- 303 See Other:臨時性重定向,且總是使用 GET 請求新的 URI
- 304 Not Modified:客戶端有緩沖的文檔并發(fā)出一個條件性的請求钝的,服務(wù)器告訴客戶原來緩存的文檔還可以繼續(xù)使用
- 307 Temporary Redirect:臨時性重定向翁垂,除GET、HEAD方法外硝桩,其他的請求方法必須等客戶確認才能跳轉(zhuǎn)
4XX:客戶端錯誤 - 請求有語法錯誤或請求無法實現(xiàn)
- 400 Bad Request:客戶端有語法錯誤沿猜,不能被服務(wù)器所理解
- 401 Unauthorized:請求未經(jīng)授權(quán),這個狀態(tài)碼必須和WWW-Authenticate報頭域一起使用
- 403 Forbidden:對被請求頁面的訪問被禁止
- 404 Not Found:請求資源不存在
5XX:服務(wù)器錯誤 - 服務(wù)器未能實現(xiàn)合法的請求
- 500 Internal Server Error:服務(wù)器發(fā)生不可預(yù)期的錯誤原來緩沖的文檔還可以繼續(xù)使用碗脊。一般來說啼肩,這個問題都會在服務(wù)器端的源代碼出現(xiàn)錯誤時出現(xiàn)
- 502 Bad Gateway:從上游服務(wù)器接收到無效的響應(yīng)
- 503 Server Unavailable:請求未完成,服務(wù)器臨時過載或宕機(可能是過載或正在維護)衙伶,一段時間后可能恢復(fù)正常祈坠。看Retry-After頭矢劲,可以預(yù)計延遲時間赦拘,如果沒給出Retry-After頭,那么客戶端應(yīng)當(dāng)以處理500響應(yīng)的方式處理它
- 504 Gateway Timeout:網(wǎng)頁請求超時
場景:訪問大流量或者內(nèi)容數(shù)據(jù)量較多的網(wǎng)站芬沉。根據(jù)我們掌握的服務(wù)器性能狀況及網(wǎng)絡(luò)流量情況躺同,合理的對nginx.conf中的字句進行合理正確的設(shè)置。
九丸逸、持久連接 - TCP connection
HTTP1.0:采用“請求-應(yīng)答”模式蹋艺,每個請求/應(yīng)答客戶和服務(wù)器都要新建一個連接,完成后立即斷開連接黄刚。
HTTP1.1:
- 當(dāng)使用普通模式捎谨,即非Keep-Alive模式時,同HTTP1.0.
- 當(dāng)使用
Keep-Alive
模式(又稱持久連接憔维、連接重用)時侍芝,Keep-Alive功能使客戶端到服務(wù)器端的連接持續(xù)有效,當(dāng)出現(xiàn)對服務(wù)器的后繼請求時埋同,Keep-Alive功能避免了建立或重新建立連接(減少三次握手的開銷)。
HTTP2.0:支持信道復(fù)用棵红,即HTTP請求支持并發(fā)凶赁。同一個用戶對同一個服務(wù)器發(fā)起網(wǎng)頁請求的時候(同域),只需要一個HTTP連接。
十虱肄、管線化
在使用持久連接的情況下致板,某個連接上消息的傳遞類似于:
請求1 -> 響應(yīng)1-> 請求2 -> 響應(yīng)2 - > 請求3 -> 響應(yīng)3
管線化之后,某個連接上的消息變成了類似這樣:
請求1 -> 請求2 -> 請求3 -> 響應(yīng)1 -> 響應(yīng)2 -> 響應(yīng)3
管線化的特點
- 管線化機制通過持久連接完成咏窿,僅HTTP/1.1支持此技術(shù)
- 只有GET和HEAD請求可以進行管線化斟或,而POST則有所限制
- 初次創(chuàng)建連接時不建議啟動管線機制,因為服務(wù)器不一定支持HTTP/1.1版本的協(xié)議
- 管線化不會影響響應(yīng)到來的順序集嵌,響應(yīng)返回的順序并未改變
- HTTP/1.1要求服務(wù)端必須支持管線化萝挤,但并不是要求服務(wù)器也對響應(yīng)進行管線化處理,只是要求對于管線化的請求不失敗即可
- 由于上面提到的服務(wù)器端問題根欧,開啟管線化很可能并不會帶來大幅度的性能提升怜珍,而且很多服務(wù)器端和代理程序?qū)芫€化的支持并不好,因此現(xiàn)代瀏覽器如Chrome和Firefox默認并未開啟管線化支持凤粗。
十一酥泛、創(chuàng)建一個web服務(wù)(基于node.js)
const http = require('http')
http.createServer(function (request, response) {
console.log('request come', request.url)
response.end('OK')
}).listen(8888)
console.log('server is listening... ')
十二、跨域通信
瀏覽器有同源策略嫌拣。協(xié)議柔袁、域名、端口有一個不同就算跨域异逐〈匪鳎跨域請求,雖然會成功应役,但是由于同源安全策略限制不會返回相應(yīng)的資源情组。
主要限制以下幾個方面:
- Cookie、LocalStorage 和 IndexDB 無法讀取
- DOM 無法獲得
- AJAX 請求不能發(fā)送
同源策略:限制從一個源加載的文檔或腳本和來自另一個源的資源進行交互箩祥。這是用于隔離潛在的惡意文件的關(guān)鍵的安全機制院崇。
前后端如何通信:
- AJAX
- WebSocket
- CORS
...
跨域通信幾種解決方案
- JSONP
- CORS(可以理解成支持跨域通信的AJAX)
- Hash
- window.name/window.postMessage(HTML5)
- WebSocket
- Proxy
12.1 JSONP
JSONP:由于同源策略的限制,XMLHttpRequest只允許請求當(dāng)前源的資源袍祖。而<script src="...">...</script>
底瓣,<img>
,<link>
標簽沒有同源限制蕉陋,所以JSONP通過聲明動態(tài)<script>
標簽捐凭,實現(xiàn)異步加載,為src指定一個跨域url凳鬓。繞過同源策略的限制茁肠,拿到數(shù)據(jù)。
JSONP由兩部分組成:回調(diào)函數(shù)和數(shù)據(jù)缩举。
回調(diào)函數(shù):當(dāng)響應(yīng)到來時應(yīng)該在頁面中調(diào)用的函數(shù)垦梆,而數(shù)據(jù)就是傳入回調(diào)函數(shù)中的JSON數(shù)據(jù)(注意圓括號和大括號的書寫)匹颤。利用回調(diào)函數(shù)處理JSON數(shù)據(jù)。
優(yōu)點:
- 兼容性好
缺點:
- 只支持GET請求托猩,不支持 POST 和其他請求
- 只支持跨域HTTP請求印蓖,不能解決不同域的兩個頁面之間如何進行JavaScript調(diào)用的問題。
簡述原理與過程:首先在客戶端注冊一個 callback, 然后把callback的名字傳給服務(wù)器京腥。此時赦肃,服務(wù)器先生成一個function , function 名字就是傳遞上來的參數(shù)。最后將 json 數(shù)據(jù)直接以入?yún)⒌姆绞焦耍胖玫?function 中他宛,這樣就生成了一段 JS 語法的文檔,返回給客戶端因悲《楣客戶端瀏覽器解析script標簽,并執(zhí)行返回的 JS 文檔晃琳,此時數(shù)據(jù)作為參數(shù)讯检,傳入客戶端預(yù)先定義好的callback 函數(shù)里。
12.2 CORS
CORS:通過設(shè)置Access-Control-Allow-Origin:'*'
來允許跨域卫旱。
*
表示所有的服務(wù)都接受允許跨域人灼,這里最好設(shè)置成特定的域名。如:'http://100.79.238.34:8888'
顾翼。
注:此屬性只能設(shè)置一個值投放,但是可以動態(tài)判斷服務(wù)允不允許跨域,允許就寫進去适贸。
優(yōu)點:
- 可用Ajax發(fā)請求獲取數(shù)據(jù)
缺點:
- 兼容性沒有JSONP好(需要瀏覽器支持XHR2)
12.2.1 CORS 預(yù)請求
CORS 限制:
- 默認只支持GET灸芳、POST、HEAD請求
- 允許的Content-Type:
text/plain
拜姿、multipart/form-data
烙样、application/x-www-form-urlencoded
- 請求頭限制
- XMLHttpRequestUpload 均沒有注冊任何事件監(jiān)聽器
- 請求中沒有使用 ReadableStream 對象
詳細限制請看官方文檔。
使用CORS預(yù)請求(preflight)蕊肥,突破跨域限制
CORS預(yù)請求:就是在發(fā)生CORS請求時谒获,瀏覽器檢測到跨域請求,會自動發(fā)出一個OPTIONS請求來檢測本次請求是否被服務(wù)器接受壁却。
一個OPTIONS請求一般會攜帶下面兩個與CORS相關(guān)的頭:
- Access-Control-Request-Method : 本次預(yù)檢請求的請求方法批狱。
- Access-Control-Request-Headers:本次請求所攜帶的自定義首部字段。
這些字段是導(dǎo)致產(chǎn)生OPTIONS請求的一個原因展东。
這樣赔硫,服務(wù)端收到該預(yù)檢請求后,會返回與CORS相關(guān)的響應(yīng)頭盐肃。主要會包括下面幾個爪膊,但可能還會有其他的有關(guān)CORS字段:
- Access-Control-Allow-Origin: 服務(wù)器允許的跨域請求源
- Access-Control-Allow-Methods: 服務(wù)器允許的請求方法
- Access-Control-Allow-Headers: 服務(wù)器允許的自定義的請求首部字段
- Access-Control-Allow-Max-Age:指定本次預(yù)檢請求的有效期向胡,單位為秒
- Access-Control-Allow-Credentials:接收跨域的Cookie
12.3 跨域相關(guān)拓展:
- 通過
NODE
發(fā)起請求可以避免 瀏覽器 的同源策略。 - nginx 設(shè)置反向代理
server {
listen 80;
server_name www.a.com;
access_log logs/test.access.log;
# 匹配以/apis/開頭的請求
location ^~ /apis/ {
proxy_pass http://www.b.com/; #注意域名后有一個/
}
location / {
root html/a;
index index.html index.htm;
}
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
還有Proxy惊完、window.name、window.postMessage 等跨域方式处硬,感興趣可以查閱相關(guān)資料小槐。
十三、緩存優(yōu)化
13.1 協(xié)議層面
- 強緩存:強緩存如果命中荷辕,瀏覽器直接從自己的緩存中讀取資源凿跳,不會發(fā)請求到服務(wù)器。
強緩存主要是采用響應(yīng)頭中的
Cache-Control
和Expires
兩個字段進行控制的疮方。其中Expires是HTTP 1.0中定義的控嗜,它指定了一個絕對的過期時期。而Cache-Control是HTTP 1.1時出現(xiàn)的緩存控制字段骡显。Cache-Control:max-age
定義了一個最大使用期疆栏,就是從第一次生成文檔到緩存不再生效的合法生存日期。由于Expires是HTTP1.0時代的產(chǎn)物惫谤,因此設(shè)計之初就存在著一些缺陷壁顶,如果本地時間和服務(wù)器時間相差太大,就會導(dǎo)致緩存錯亂溜歪。這兩個字段同時使用的時候Cache-Control的優(yōu)先級給更高一點若专。 這兩個字段的效果是類似的,客戶端都會通過對比本地時間和服務(wù)器生存時間來檢測緩存是否可用蝴猪。如果緩存沒有超出它的生存時間內(nèi)调衰,客戶端就會直接采用本地的緩存。如果生存日期已經(jīng)過了自阱,這個緩存也就宣告失效嚎莉。接著客戶端將再次與服務(wù)器進行通信來驗證這個緩存是否需要更新。
- 協(xié)商緩存:當(dāng)強緩存沒有命中的時候动壤,瀏覽器一定會發(fā)送一個請求到服務(wù)器萝喘,通過服務(wù)器端依據(jù)資源的另外一些
http header
驗證這個資源是否命中協(xié)商緩存,如果協(xié)商緩存命中琼懊,服務(wù)器會將這個請求返回(304
)阁簸,若未命中請求,則將資源返回客戶端哼丈,并更新本地緩存數(shù)據(jù)(200
)启妹。
強緩存機制如果檢測到緩存失效,就需要進行服務(wù)器再驗證醉旦。這種緩存機制也稱作協(xié)商緩存饶米。瀏覽器在第一次獲取請求的時候桨啃,就會在響應(yīng)頭中攜帶上資源的上次服務(wù)器修改日期(Last-Modified)或者資源的標簽(Etag)。后續(xù)的請求服務(wù)器會根據(jù)請求頭上的If-Modified-Since(對應(yīng)Last-Modified)和(If-None-Match)字段來判斷資源是否失效檬输,一旦資源過期照瘾,則服務(wù)器會重新發(fā)送新的資源到客戶端上,從而保證資源的有效性丧慈。
另外一種協(xié)商緩存的校驗方式的通過校驗碼而不是時間析命,這樣就保證了在文件內(nèi)容不變的情況下不會重復(fù)占用網(wǎng)絡(luò)資源。響應(yīng)頭中Etag字段是服務(wù)器給資源打上的一個標記逃默,利用這個標記就可以實現(xiàn)緩存的更新鹃愤。后續(xù)發(fā)起的請求,會在請求頭上附帶上If-None-Match字段完域,其值就是這個標記的值软吐。
需要注意的是當(dāng)響應(yīng)頭中同時存在Etag和Last-Modified的時候,會先對Etag進行比對吟税,隨后才是Last-Modified凹耙。
13.1.1 Cache-control
可緩存性
- public:任何地方
- private:只有發(fā)起請求的瀏覽器
- no-cache:任何節(jié)點都不可以
到期
- max-age=<seconds>:瀏覽器默認讀取
- s-maxage=<seconds>:代理服務(wù)器優(yōu)先讀取
- max-stale=<seconds>:如果有此設(shè)置,即便過期了也還可以使用緩存(在發(fā)起端設(shè)置生效)
重新驗證
- must-revalidate
- proxy-revalidate
其他
- no-store:希望代理服務(wù)器乌妙,去服務(wù)器端拿新的
- no-transform :希望代理服務(wù)器不要改返回的內(nèi)容
代理服務(wù)器如:Nginx
13.1.2 HTTP頭信息控制緩存
Expires
(強緩存)+ 過期時間 :
Expires
是HTTP1.0
提出的一個表示資源過期時間的header
使兔,它描述的是一個絕對時間。
Cache-control
(強緩存):
描述的是一個相對時間藤韵,在進行緩存命中的時候虐沥,都是利用客戶端時間進行判斷。管理更有效泽艘,安全一些欲险。如:Cache-Control: max-age=3600
服務(wù)端返回頭Last-Modified/
客戶端請求頭If-Modified-Since
(協(xié)商緩存):
標示這個響應(yīng)資源的最后修改時間。Last-Modified是服務(wù)器相應(yīng)給客戶端的匹涮,If-Modified-Sinces是客戶端發(fā)給服務(wù)器天试,服務(wù)器判斷這個緩存時間是否是最新的,是的話拿緩存然低。
服務(wù)端返回頭Etag
/客戶端請求頭If-None-Match
(協(xié)商緩存):
etag和last-modified類似喜每,用來發(fā)送一個字符串來標識版本。
強緩存不請求服務(wù)器雳攘,客戶端判斷協(xié)商緩存要請求服務(wù)器带兜。
注:有時需要將靜態(tài)資源強制更新,通用的方法是給靜態(tài)資源文件添加hash(md5)后綴
13.2 瀏覽器層面
13.2.1 WebStorage
WebStorage是HTML5中新增的本地存儲(存儲在客戶端)的解決方案之一吨灭。
WebStorage提供兩種類型的API:localStorage和sessionStorage刚照。
為保證使用
localStorage.setItem
等API不報錯,使用時盡量加入到try-catch
中喧兄,因為某些瀏覽器是禁用這個 API 的无畔。
localstorage(常用)
?localStorage一般用來存儲應(yīng)用數(shù)據(jù)(不重要但是不經(jīng)常設(shè)置的信息)啊楚,也可以利用其存儲js和css等靜態(tài)資源。作為一種性能優(yōu)化的方案浑彰,這種方法也曾被大量應(yīng)用于移動端的網(wǎng)頁中恭理。不過缺點也很明顯,由于localStorage是保存在本地中的郭变,所以很容易導(dǎo)致 XSS 注入攻擊蚯斯。如果要使用這種方案,一定要做好對應(yīng)的安全措施饵较。
特點:
- 永久有效
- 存儲量增大到 5MB
- 瀏覽器端(客戶端)緩存,不參與和服務(wù)器的通信(不會帶到 HTTP 請求中)
- API 適用于數(shù)據(jù)存儲
localStorage.setItem(key, value)
localStorage.getItem(key)
sessionStorage
存放一些需要及時失效的重要信息
特點:
- 僅在當(dāng)前會話下有效遭赂,關(guān)閉頁面或瀏覽器后被清除
- 存儲量增大到 5MB
13.2.2 Cookie
讀取循诉、添加和更新文檔所關(guān)聯(lián)的 cookie :document.cookie = ....
缺點:
- 存放數(shù)據(jù)大小:4KB左右(cookie的長度和數(shù)量有所限制撇他。每個domain最多只能有20條cookie茄猫,每個cookie長度不能超過4KB。否則會被截掉困肩。)
- 個數(shù)限制:不超過20個
- 每次都會攜帶在HTTP頭中划纽,使用cookie保存過多數(shù)據(jù)會帶來性能問題
- 需要自己封裝,原生的接口不友好
- 安全性問題
注意事項:
- 通過良好的編程锌畸,控制保存在cookie中的session對象的大小勇劣。
- 通過加密和安全傳輸技術(shù),減少cookie被破解的可能性潭枣。
- 在cookie中存放不敏感的數(shù)據(jù)比默,即使被盜取也不會有很大的損失。
- 控制cookie的生命期盆犁,使之不會永遠有效命咐。這樣的話偷盜者很可能拿到的是一個過期的cookie。
- 有些狀態(tài)不可以保存在客戶端谐岁。例如醋奠,為了防止重復(fù)提交表單,我們需要在服務(wù)端保存一個計數(shù)器伊佃。若把計數(shù)器保存在客戶端窜司,則起不到什么作用。
13.2.3 IndexedDB
通俗地說锭魔,IndexedDB 就是瀏覽器提供的本地數(shù)據(jù)庫例证,它可以被網(wǎng)頁腳本創(chuàng)建和操作。IndexedDB 允許儲存大量數(shù)據(jù)迷捧,提供查找接口织咧,還能建立索引胀葱。這些都是 LocalStorage 所不具備的。就數(shù)據(jù)庫類型而言笙蒙,IndexedDB 不屬于關(guān)系型數(shù)據(jù)庫(不支持 SQL 查詢語句)抵屿,更接近 NoSQL 數(shù)據(jù)庫。
IndexedDB 具有以下特點捅位。
(1)鍵值對儲存轧葛。 IndexedDB 內(nèi)部采用對象倉庫(object store)存放數(shù)據(jù)。所有類型的數(shù)據(jù)都可以直接存入艇搀,包括 JavaScript 對象尿扯。對象倉庫中,數(shù)據(jù)以"鍵值對"的形式保存焰雕,每一個數(shù)據(jù)記錄都有對應(yīng)的主鍵衷笋,主鍵是獨一無二的,不能有重復(fù)矩屁,否則會拋出一個錯誤辟宗。
(2)異步。 IndexedDB 操作時不會鎖死瀏覽器吝秕,用戶依然可以進行其他操作泊脐,這與 LocalStorage 形成對比,后者的操作是同步的烁峭。異步設(shè)計是為了防止大量數(shù)據(jù)的讀寫容客,拖慢網(wǎng)頁的表現(xiàn)。
(3)支持事務(wù)约郁。 IndexedDB 支持事務(wù)(transaction)耘柱,這意味著一系列操作步驟之中,只要有一步失敗棍现,整個事務(wù)就都取消调煎,數(shù)據(jù)庫回滾到事務(wù)發(fā)生之前的狀態(tài),不存在只改寫一部分數(shù)據(jù)的情況己肮。
(4)同源限制 IndexedDB 受到同源限制士袄,每一個數(shù)據(jù)庫對應(yīng)創(chuàng)建它的域名。網(wǎng)頁只能訪問自身域名下的數(shù)據(jù)庫谎僻,而不能訪問跨域的數(shù)據(jù)庫娄柳。
(5)儲存空間大 IndexedDB 的儲存空間比 LocalStorage 大得多,一般來說不少于 250MB艘绍,甚至沒有上限赤拒。
(6)支持二進制儲存。 IndexedDB 不僅可以儲存字符串,還可以儲存二進制數(shù)據(jù)(ArrayBuffer 對象和 Blob 對象)挎挖。
十四这敬、Cookie和Session有什么聯(lián)系和區(qū)別
14.1 Cookie
- 通過Set-Cookie
- 下次請求就會自動帶上
- 鍵值對,可以設(shè)置多個
14.1.1 Cookie屬性
- max-age和expires:設(shè)置過期時間
- Secure:只在https的時候發(fā)送
- HttpOnly:無法通過document.cookie訪問(禁止重要數(shù)據(jù)通過JS訪問蕉朵,提高安全性崔涂,防止CSRF攻擊)
14.2 Cookie 和 Session 的區(qū)別
- cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上始衅。
session會在一定時間內(nèi)保存在服務(wù)器上冷蚂。當(dāng)訪問增多,會比較占用服務(wù)器的性能
考慮到減輕服務(wù)器性能方面汛闸,應(yīng)當(dāng)使用cookie蝙茶。
- session比cookie更安全
cookie不是很安全,可以通過分析存放在本地的cookie并進行cookie欺騙诸老。
- 一般用cookie來存儲session id
- 單個cookie保存的數(shù)據(jù)不能超過4K尸闸,很多瀏覽器都限制一個站點最多保存20個cookie。
建議:
- 將登錄信息等敏感信息存放為session
- 其他信息如果需要保留孕锄,可以放在cookie中
十五、內(nèi)容安全策略(CSP:Content Security Policy)
15.1 作用
- 限制資源獲取
- 報告資源獲取越權(quán)
15.2 限制方式
- default-src限制全局
- 指定資源類型 如:img-src
- report-uri: 檢測限制規(guī)則
- 建議在HTTP的Header中設(shè)置苞尝,也可以在meta標簽里設(shè)置
詳見:內(nèi)容安全策略( CSP ) - HTTP | MDN
十六畸肆、HTTPS(HyperText Transfer Protocol over Secure Socket Layer)
HTTPS:主要是HTTP下增加了SSL(安全套接層)或者TSL(傳輸層安全),在SSL或TSL在傳輸層對數(shù)據(jù)進行了加密處理宙址。
HTTPS協(xié)議的主要作用:
- 建立一個信息安全通道轴脐,來保證數(shù)據(jù)傳輸?shù)陌踩?/li>
- 確認網(wǎng)站的真實性。
16.1 HTTP與HTTPS的區(qū)別
① HTTPS協(xié)議需要到CA申請證書抡砂,一般免費證書很少大咱,需要付費。SSL依靠證書來驗證服務(wù)器的身份注益,并為瀏覽器和服務(wù)器之間的通信加密碴巾。
② HTTP是超文本傳輸協(xié)議,信息是明文傳輸丑搔,HTTPS則是具有安全性的SSL加密傳輸協(xié)議厦瓢。
③ HTTP和HTTPS使用的是完全不同的連接方式,用的端口也不一樣啤月,前者是80煮仇,后者是443。
④ HTTP的連接很簡單谎仲,是無狀態(tài)的浙垫;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認證的網(wǎng)絡(luò)協(xié)議,比HTTP協(xié)議安全夹姥。
16.2 HTTPS如何加密
私鑰
解密杉武,放在服務(wù)器上
公鑰
放在互聯(lián)網(wǎng)上所有人都能拿到的加密字符串,加密
客戶端在使用HTTPS方式與Web服務(wù)器通信時有以下幾個步驟:
(1)客戶使用HTTPS的URL訪問Web服務(wù)器佃声,要求與Web服務(wù)器建立SSL連接艺智。
(2)Web服務(wù)器收到客戶端請求后,會將網(wǎng)站的證書信息(證書中包含公鑰)傳送一份給客戶端圾亏。
(3)客戶端的瀏覽器與Web服務(wù)器開始協(xié)商SSL連接的安全等級十拣,也就是信息加密的等級。
(4)客戶端的瀏覽器根據(jù)雙方同意的安全等級志鹃,建立會話密鑰夭问,然后利用網(wǎng)站的公鑰將會話密鑰加密,并傳送給網(wǎng)站曹铃。
(5)Web服務(wù)器利用自己的私鑰解密出會話密鑰(主密鑰)缰趋,中間人無法解密。
(6)Web服務(wù)器利用會話密鑰加密與客戶端之間的通信陕见。