HTTP - HTTP報文首部

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、空行

一. 請求報文

image

二. 響應(yīng)報文

image

三. 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報文的組成部分

  1. 請求報文
    • 請求行(首行):HTTP方法、頁面地址(/表示首頁)、HTTP協(xié)議/版本
    • 請求頭:HTTP協(xié)議告訴服務(wù)端要哪些內(nèi)容(key/value值)
    • 空行:告訴服務(wù)端,請求頭部分結(jié)束
    • 請求體
  2. 響應(yīng)報文
    • 狀態(tài)行:HTTP協(xié)議、狀態(tài)碼
    • 響應(yīng)頭
    • 空行
    • 響應(yīng)體

2.1 瀏覽器輸入一個url后關(guān)于HTTP請求發(fā)生了什么

image

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)頁的地址,當前請求網(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 請求變量的實體標簽的當前值 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:

  1. 只有一個命令GET
  2. 沒有 header 等描述數(shù)據(jù)的信息
  3. 服務(wù)器發(fā)送完畢,就關(guān)閉TCP連接

HTTP/1.0:

  1. 增加了很多命令
  2. 增加了status code 和 header
  3. 多字符集支持、多部分發(fā)送、權(quán)限和緩存等

HTTP/1.1:

  1. 持久連接
  2. pipeline
  3. 增加 host (可以在一個集群上同時跑多個web服務(wù),通過host字段來判斷使用node還是Java服務(wù),提高物理服務(wù)的使用效率)和其他一些命令

HTTP/2.0:

  1. 分幀傳輸:所有數(shù)據(jù)以二進制(幀)傳輸,之前都是用字符串
  2. 多路復用(信道復用):同一個連接中發(fā)送多個請求,不再需要按照順序來
  3. 頭信息壓縮(之前都是完整發(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確認報文)今天...(開始吐槽)
圖例:

image
  • 第一次握手(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),當服務(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后......
客戶:我知道了。
啪?。ㄟ@才斷開連接)
圖例:

image
  • 第一次揮手(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é)流 面向報文
效率 傳輸效率低 傳輸效率高
雙工性 全雙工 一對一、一對多、多對一、多對多
流量控制 有(滑動窗口)
擁塞控制 有(慢開始、擁塞避免、快重傳、快恢復)

六、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風格的接口。

七、POST和GET區(qū)別

場景 GET POST
瀏覽器回退 無害的 會重復提交請求
產(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ù)器臨時過載或宕機(可能是過載或正在維護),一段時間后可能恢復正常??碦etry-After頭,可以預(yù)計延遲時間,如果沒給出Retry-After頭,那么客戶端應(yī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:

  • 當使用普通模式,即非Keep-Alive模式時,同HTTP1.0.
  • 當使用Keep-Alive模式(又稱持久連接、連接重用)時,Keep-Alive功能使客戶端到服務(wù)器端的連接持續(xù)有效,當出現(xiàn)對服務(wù)器的后繼請求時,Keep-Alive功能避免了建立或重新建立連接(減少三次握手的開銷)。

HTTP2.0:支持信道復用,即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只允許請求當前源的資源。而<script src="...">...</script>,<img><link>標簽沒有同源限制,所以JSONP通過聲明動態(tài)<script>標簽,實現(xiàn)異步加載,為src指定一個跨域url。繞過同源策略的限制,拿到數(shù)據(jù)。

JSONP由兩部分組成:回調(diào)函數(shù)數(shù)據(jù)

回調(diào)函數(shù):當響應(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 語法的文檔,返回給客戶端??蛻舳藶g覽器解析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:本次請求所攜帶的自定義首部字段。

這些字段是導致產(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-ControlExpires兩個字段進行控制的。其中Expires是HTTP 1.0中定義的,它指定了一個絕對的過期時期。而Cache-Control是HTTP 1.1時出現(xiàn)的緩存控制字段。Cache-Control:max-age定義了一個最大使用期,就是從第一次生成文檔到緩存不再生效的合法生存日期。由于Expires是HTTP1.0時代的產(chǎn)物,因此設(shè)計之初就存在著一些缺陷,如果本地時間和服務(wù)器時間相差太大,就會導致緩存錯亂。這兩個字段同時使用的時候Cache-Control的優(yōu)先級給更高一點。 這兩個字段的效果是類似的,客戶端都會通過對比本地時間和服務(wù)器生存時間來檢測緩存是否可用。如果緩存沒有超出它的生存時間內(nèi),客戶端就會直接采用本地的緩存。如果生存日期已經(jīng)過了,這個緩存也就宣告失效。接著客戶端將再次與服務(wù)器進行通信來驗證這個緩存是否需要更新。

  • 協(xié)商緩存:當強緩存沒有命中的時候,瀏覽器一定會發(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)容不變的情況下不會重復占用網(wǎng)絡(luò)資源。響應(yīng)頭中Etag字段是服務(wù)器給資源打上的一個標記,利用這個標記就可以實現(xiàn)緩存的更新。后續(xù)發(fā)起的請求,會在請求頭上附帶上If-None-Match字段,其值就是這個標記的值。
需要注意的是當響應(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(強緩存)+ 過期時間 :
ExpiresHTTP1.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是保存在本地中的,所以很容易導致 XSS 注入攻擊。如果要使用這種方案,一定要做好對應(yīng)的安全措施。

特點

  1. 永久有效
  2. 存儲量增大到 5MB
  3. 瀏覽器端(客戶端)緩存,不參與和服務(wù)器的通信(不會帶到 HTTP 請求中)
  4. API 適用于數(shù)據(jù)存儲 localStorage.setItem(key, value) localStorage.getItem(key)
sessionStorage

存放一些需要及時失效的重要信息

特點

  1. 僅在當前會話下有效,關(guān)閉頁面或瀏覽器后被清除
  2. 存儲量增大到 5MB

13.2.2 Cookie

讀取、添加和更新文檔所關(guān)聯(lián)的 cookie :document.cookie = ....

缺點

  • 存放數(shù)據(jù)大?。?KB左右(cookie的長度和數(shù)量有所限制。每個domain最多只能有20條cookie,每個cookie長度不能超過4KB。否則會被截掉。)
  • 個數(shù)限制:不超過20個
  • 每次都會攜帶在HTTP頭中,使用cookie保存過多數(shù)據(jù)會帶來性能問題
  • 需要自己封裝,原生的接口不友好
  • 安全性問題

注意事項

  1. 通過良好的編程,控制保存在cookie中的session對象的大小。
  2. 通過加密和安全傳輸技術(shù),減少cookie被破解的可能性。
  3. 在cookie中存放不敏感的數(shù)據(jù),即使被盜取也不會有很大的損失。
  4. 控制cookie的生命期,使之不會永遠有效。這樣的話偷盜者很可能拿到的是一個過期的cookie。
  5. 有些狀態(tài)不可以保存在客戶端。例如,為了防止重復提交表單,我們需要在服務(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)的主鍵,主鍵是獨一無二的,不能有重復,否則會拋出一個錯誤。

(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ù)器上。當訪問增多,會比較占用服務(wù)器的性能
考慮到減輕服務(wù)器性能方面,應(yīng)當使用cookie。

  • session比cookie更安全

cookie不是很安全,可以通過分析存放在本地的cookie并進行cookie欺騙。

  • 一般用cookie來存儲session id
  • 單個cookie保存的數(shù)據(jù)不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。

建議

  1. 將登錄信息等敏感信息存放為session
  2. 其他信息如果需要保留,可以放在cookie中

十五、內(nèi)容安全策略(CSP:Content Security Policy)

15.1 作用

  1. 限制資源獲取
  2. 報告資源獲取越權(quán)

15.2 限制方式

  1. default-src限制全局
  2. 指定資源類型 如:img-src
  3. report-uri: 檢測限制規(guī)則
  4. 建議在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é)議的主要作用:

  1. 建立一個信息安全通道,來保證數(shù)據(jù)傳輸?shù)陌踩?/li>
  2. 確認網(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)上所有人都能拿到的加密字符串,加密

image

客戶端在使用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ù)器利用會話密鑰加密與客戶端之間的通信。

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

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

  • 作者:李成文;標簽: http首部 HTTP報文首部 HTTP協(xié)議的請求和響應(yīng)報文中必定包含HTTP首部。首部內(nèi)容...
    廣州蘆葦科技web前端閱讀 1,199評論 0 0
  • 本文是《圖解HTTP》讀書筆記的第二篇,主要包括此書的第六章內(nèi)容,因為第六章的內(nèi)容較多,而且比較重要,所以單獨寫為...
    lijiankun24閱讀 1,498評論 0 6
  • HTTP報文首部 ??HTTP協(xié)議的請求和響應(yīng)報文中必定包含HTTP首部。首部內(nèi)容為客戶端和服務(wù)器分別處理請求和響...
    JarvanZ閱讀 858評論 0 0
  • 1. HTTP報文首部 HTTP協(xié)議的請求和響應(yīng)報文中必定包含HTTP首部。首部內(nèi)容為客戶端和服務(wù)器分別處理請求和...
    笙繩省盛閱讀 1,954評論 0 5
  • 教育的路上,老師和家長們總是在不斷地向前摸索,四處尋找更佳的方法;如今的教育者們,無論是家里的父母,還是在校...
    羅靖方閱讀 1,163評論 0 1

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