(2.6w字)網絡知識點靈魂拷問(下)——前端面試必問

關注公衆號「執鳶者」,獲取大量教學視頻並進入專業交流羣css


11、HTTP協議(請求報文和響應報文)


11.1 請求報文html

HTTP請求報文主要包括:請求行、請求頭部以及請求的數據(實體)。
1.請求行:方法字段、URI字段和協議版本
方法字段:GET(請求獲取內容)、POST(提交表單)、HEAD(請求資源響應消息報頭)、PUT(傳輸文件)、DELETE(請求刪除URI指向的資源)、OPTIONS(查詢針對請求URI指定的資源支持的方法)、TRACE(追蹤請求通過路徑)、CONNECT(要求用隧道協議鏈接代理)
2.請求頭部
常見標頭有:Connection標頭(鏈接管理)、Host標頭(指定請求資源的主機)、Range標頭(請求實體的字節範圍)、User-Agent標頭(包含發出請求的用戶信息)、Accept標頭(首選的媒體類型)、Accept-Language(首選的天然語言)
前端

3.HTTP請求的body主要用於提交表單場景。實際上,http請求的bodt是比較自由的,只要瀏覽器端發送的body服務端承認就能夠了。一些常見的body格式是:nginx


application/json
application/x-www-form-urlencoded
multipart/form-data
text/xmlweb

使用html的form標籤提交產生的html請求,默認會產生 application/x-www-form-urlencoded 的數據格式,當有文件上傳時,則會使用multipart/form-data。算法

11.2 響應報文

HTTP響應報文分爲三個部分:狀態行、首部行和實體;
1.狀態行:版本、狀態碼和緣由語句
狀態碼:
(1)1xx:這一類型的狀態碼,表明請求已被接受,須要繼續處理。這類響應是臨時響應,只包含狀態行和某些可選的響應頭信息,並以空行結束;
(2)2xx:這一類型的狀態碼,表明請求已成功被服務器接收、理解並接受;
(3)3xx:這類狀態碼錶明須要客戶端採起進一步的操做才能完成請求。一般,這些狀態碼用來重定向,後續的請求地址(重定向目標)在本次響應的Location域中指明。
(4)4xx:這類狀態碼錶明客戶端類的錯誤;
(5)5xx:服務器類的錯誤。
200---OK/請求已經正常處理完畢
204---請求處理成功,但沒有資源返回
206---表示客戶端進行了範圍請求,而服務器成功執行了這部分的GET請求
301---/請求永久重定向 被請求的資源已永久移動到新位置,而且未來任何對此資源的引用都應該使用本響應返回的若干個 URI 之一。若是可能,擁有連接編輯功能的客戶端應當自動把請求的地址修改成從服務器反饋回來的地址。
302---/請求臨時重定向 因爲這樣的重定向是臨時的,客戶端應當繼續向原有地址發送之後的請求。只有在Cache-Control或Expires中進行了指定的狀況下,這個響應纔是可緩存的。
303---表示因爲請求對應的資源存在着另外一個URI,應使用GET方法定向獲取請求的資源
304---/表示客戶端發送附帶條件的請求(指採用GET方法的請求報文中包含If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since中任一首部)時,服務端容許請求訪問資源,但未知足條件的狀況
307---臨時重定向,與302含義相同,可是307會遵守瀏覽器標準,不會從POST變成GET
400---/客戶端請求存在語法錯誤
401---/當前請求須要用戶驗證。
403---/服務器已經理解請求,可是拒絕執行它。與401響應不一樣的是,身份驗證並不能提供任何幫助
404---/請求失敗,請求所但願獲得的資源未被在服務器上發現。
405---/請求行中指定的請求方法不能被用於請求相應的資源。
500---/服務器遇到了一個不曾預料的情況,致使了它沒法完成對請求的處理。
501---/服務器不支持當前請求所須要的某個功能。當服務器沒法識別請求的方法,而且沒法支持其對任何資源的請求。
503---/因爲臨時的服務器維護或者過載,服務器當前沒法處理請求。
505---/服務器不支持,或者拒絕支持在請求中使用的 HTTP 版本。
2.響應首部
Date(響應的時間)、Via(報文通過的中間節點)、Last-Modified(上一次修改時間)、Etag(與此實體相關的實體標記)、Connection(鏈接狀態)、Accept-Ranges(服務器可接收的範圍類型)、Content-Type(資源類型)
chrome


12、Cookie和Session

12.1 Cookie 大小4KB

Cookie的工做機制是用戶識別及狀態管理。數據庫

1.Set-Cookie
該首部字段用來告知客戶端有關Cookie的各類信息
json

2.Cookie
該首部字段用來告知服務器,當客戶端想得到HTTP狀態管理支持時,就會在請求中包含從服務器接收到的Cookie。
3.HTTP是無狀態的協議,即HTTP協議自身不對請求和響應之間的通訊狀態進行保存。但爲了實現指望的保持狀態功能,因而引入了Cookie技術。
Cookie會根據從服務端發送的響應報文內的一個叫作Set-Cookie的首部字段信息,通知客戶端保存Cookie。當下次客戶端再往該服務器發送請求時,客戶端會自動在請求報文中加入Cookie值發送出去。
後端

4.expires/Max-Age 字段爲此cookie超時時間。若設置其值爲一個時間,那麼當到達此時間後,此cookie失效。不設置的話默認值是Session,意思是cookie會和session一塊兒失效。當瀏覽器關閉(不是瀏覽器標籤頁,而是整個瀏覽器) 後,此cookie失效。


12.2 Session

Session是另外一種記錄客戶狀態的機制,不一樣的是Cookie保存在客戶端瀏覽器中,而Session保存在服務器上。客戶端瀏覽器訪問服務器的時候,服務器把客戶端信息以某種形式記錄在服務器上。這就是Session。客戶端瀏覽器再次訪問時只須要從該Session中查找該客戶的狀態就能夠了。
1.後端怎麼存儲session?
在服務器內存中開闢一塊地址空間,專門存放每一個客戶端的私有數據,每一個客戶端根據cookie中保持的sessionId,能夠獲取到session數據。

12.3 Cookie與Session區別

1)、Cookie和Session都是會話技術,Cookie是運行在客戶端,Session是運行在服務器端。
2)、Cookie有大小限制4K以及瀏覽器在存cookie的個數也有限制,Session是沒有大小限制和服務器的內存大小有關。
3)、Cookie有安全隱患,經過攔截或本地文件找獲得你的cookie後能夠進行攻擊。
4)、Session是保存在服務器端上會存在一段時間纔會消失,若是session過多會增長服務器的壓力。
session用於保存重要的信息,cookie用於保存不重要的用戶信息

十3、登錄驗證

因爲HTTP是無狀態的,一次請求結束,鏈接斷開,下次服務器再收到請求,它就不知道這個請求是哪一個用戶發過來的。因此須要狀態管理,以便服務端可以準確的知道http請求是哪一個用戶發起的,從而判斷用戶是否有權限繼續這個請求。這個過程就是常說的會話管理。

13.1 同域登錄

若是前端,後臺API部署在同域下,不存在跨域的狀況,登陸方式相對簡單
1.基於Session登陸
服務器端使用Session技術,瀏覽器端使用Cookie技術。

session在一開始並不具有會話管理的做用。它只有在用戶登陸認證成功以後,而且往sesssion對象裏面放入了用戶登陸成功的憑證,才能用來管理會話。管理會話的邏輯也很簡單,只要拿到用戶的session對象,看它裏面有沒有登陸成功的憑證,就能判斷這個用戶是否已經登陸。當用戶主動退出的時候,會把它的session對象裏的登陸憑證清掉。因此在用戶登陸前或退出後或者session對象失效時,確定都是拿不到須要的登陸憑證的。
其實上述能夠解釋爲:
登陸時帶着自身的用戶名和密碼,將用戶登陸成功的憑證信息存儲在Session中,並生成Cookie,並經過Set-Cookie在響應中返回;第二次登錄時,在請求中添加Cookie後發送,服務端檢查Cookie,而後進行響應。
2.基於Token登陸

(1).用戶在瀏覽器中輸入用戶和密碼,後臺服務器經過加密或者其餘邏輯,生成一個Token。
(2).前端獲取到Token,存儲到cookie或者localStorage中,在接下來的請求中,將token經過url參數或者HTTP Header頭部傳入到服務器
(3).服務器獲取token值,經過查找數據庫判斷當前token是否有效


13.2 跨域登錄

因爲瀏覽器同源策略,凡是發送請求的url的協議、域名和端口號三者之間任意一個與當前頁面不一樣則視爲跨域
1.解決同源策略
基於Session和Token登陸都要解決
經過在服務端設置Header,設置Access-Control-Allow-Origin
若是要發送Cookie,Access-Control-Allow-Origin就不能設置星號,必須指定明確的、與請求網頁一致的域名。
2.解決請求帶上Cookie信息
CORS默認不發送Cookie和HTTP認證信息,一方面服務器制定Access-Control-Allow-Credentials:true 另外一方面開發者必須在Ajax請求中添加withCredentials屬性。

十4、HTTP1.0、HTTP1.一、HTTP2.0

14.1 HTTP的基本優化

影響HTTP網絡請求的因素主要有兩個:帶寬和延遲
1.帶寬
已經獲得極大提高
2.延遲
(1)瀏覽器阻塞:瀏覽器對於同一個域名,同時只能有6個鏈接(不一樣瀏覽器不一樣),超過瀏覽器最大鏈接數限制,後續請求就會被阻塞。
(2)DNS查詢:瀏覽器須要知道目標服務器的IP才能創建鏈接,一般能夠利用DNS緩存結果來達到減小這個時間的目的。
(3)創建鏈接:HTTP 是基於 TCP 協議的,瀏覽器最快也要在第三次握手時才能捎帶 HTTP 請求報文,達到真正的創建鏈接,可是這些鏈接沒法複用會致使每次請求都經歷三次握手和慢啓動。三次握手在高延遲的場景下影響較明顯,慢啓動則對文件類大請求影響較大。

14.2 HTTP1.0和HTTP1.1的一些區別

1.緩存處理 在HTTP1.0中主要使用header裏的If-Modified-Since,Expires來作爲緩存判斷的標準,HTTP1.1則引入了更多的緩存控制策略例如Etag,If-Unmodified-Since, If-Match, If-None-Match等更多可供選擇的緩存頭來控制緩存策略。
2.帶寬優化及網絡鏈接的使用 HTTP1.0中,存在一些浪費帶寬的現象,例如客戶端只是須要某個對象的一部分,而服務器卻將整個對象送過來了,而且不支持斷點續傳功能,HTTP1.1則在請求頭引入了range頭域,它容許只請求資源的某個部分,即返回碼是206(Partial Content),這樣就方便了開發者自由的選擇以便於充分利用帶寬和鏈接。
3.錯誤通知的管理
在HTTP1.1中新增了24個錯誤狀態響應碼,如409(Conflict)表示請求的資源與資源的當前狀態發生衝突;410(Gone)表示服務器上的某個資源被永久性的刪除。
4.Host頭處理
在HTTP1.0中認爲每臺服務器都綁定一個惟一的IP地址,所以,請求消息中的URL並無傳遞主機名(hostname)。但隨着虛擬主機技術的發展,在一臺物理服務器上能夠存在多個虛擬主機(Multi-homed Web Servers),而且它們共享一個IP地址。HTTP1.1的請求消息和響應消息都應支持Host頭域,且請求消息中若是沒有Host頭域會報告一個錯誤(400 Bad Request)。
5.長鏈接 HTTP 1.1支持長鏈接(PersistentConnection)和管線化處理,在一個TCP鏈接上能夠傳送多個HTTP請求和響應,減小了創建和關閉鏈接的消耗和延遲,在HTTP1.1中默認開啓Connection:keep-alive,必定程度上彌補了HTTP1.0每次請求都要建立鏈接的缺點。

14.3 擴展:HTTP1.1的幾個特色

1.持久鏈接 每一個TCP鏈接開始都有三次握手,要經歷一次客戶端與服務器間完整的往返,而開啓了持久化鏈接就能沒必要每次都要握手。
持久化鏈接Connection:keep-alive

2.HTTP管道
持久HTTP屢次請求必須嚴格知足先進先出(FIFO)的隊列順序:發送請求,等待響應完成,再發送客戶端隊列中的下一個請求。
HTTP管道可讓咱們把FIFO隊列從客戶端(請求隊列)遷移到服務器(響應隊列)。
但HTTP 1.x不容許一個鏈接上的多個響應數據交錯到達(多路複用),於是一個響應必須徹底返回後,下一個響應纔會開始傳輸。


14.4 HTTP的瓶頸

一條鏈接上只可發送一個請求;
請求只能從客戶端開始。客戶端不能夠接收除響應之外的指令;
請求/響應首部未經壓縮就發送。首部信息越多延遲越大;
發送冗長的首部。每次互相發送相同的首部形成的浪費較多;
可任意選擇數據壓縮格式。非強制壓縮發送;

14.5 HTTP2.0

HTTP2.0是在SPDY基礎上造成的下一代互聯網通訊協議。HTTP/2的目的是經過支持請求和響應的多路複用來減小延遲,經過壓縮HTTP首部字段將協議開銷下降,同時增長請求優先級和服務端推送的支持。
1、HTTP2.0相對於HTTP1.X的新特性
1.二進制分幀層
二進制分幀層是HTTP2.0性能加強的核心
HTTP 1.x在應用層以純文本的形式進行通訊,而HTTP 2.0將全部的傳輸信息分割爲更小的消息和幀,並對它們採用二進制格式編碼。這樣,客戶端和服務端都須要引入新的二進制編碼和解碼的機制
(1)幀
HTTP2.0通訊的最小單位,包括幀首部、流標識符、優先值和幀淨荷等。

其中,幀類型又能夠分爲:
DATA:用於傳輸HTTP消息體;
HEADERS:用於傳輸首部字段;
SETTINGS:用於約定客戶端和服務端的配置數據。好比設置初識的雙向流量控制窗口大小;
WINDOWUPDATE:用於調整個別流或個別鏈接的流量
PRIORITY:用於指定或從新指定引用資源的優先級。
RST_STREAM:用於通知流的非正常終止。
PUSH
 PROMISE:服務端推送許可。
PING:用於計算往返時間,執行「 活性」 檢活。
GOAWAY:用於通知對端中止在當前鏈接中建立流。
(2)消息
消息是指邏輯上的HTTP消息(請求/響應)。一系列數據幀組成了一個完整的消息。
(3)流
流是鏈接中的一個虛擬信道,能夠承載雙向消息傳輸。每一個流有惟一整數標識符。爲了防止兩端流ID衝突,客戶端發起的流具備奇數ID,服務端發起的流具備偶數ID。
全部HTTP2.0通訊都在一個TCP鏈接上完成,這個鏈接能夠承載任意數量的雙向數據流Stream。相應地,每一個數據流以消息的形式發送,而消息由一個或多個幀組成,這些幀能夠亂序發送,而後根據每一個幀首部的流標識符從新組裝。
2.多路複用共享鏈接 HTTP消息被分解爲獨立的幀,而不破壞消息自己的語義,交錯發送出去,最後在另外一端根據流ID和首部將它們從新組合起來。
HTTP2.0成功解決了HTTP1.x的隊首阻塞問題(TCP層的阻塞仍沒法解決),同時減小了TCP鏈接數對服務器性能有很大提高。


  • 能夠並行交錯地發送請求,請求之間互不影響; 能夠並行交錯地發送響應,響應之間互不干擾;只使用一個鏈接便可並行發送多個請求和響應; 消除沒必要要的延遲,從而減小頁面加載的時間;沒必要再爲繞過 HTTP 1.x 限制而多作不少工做;

3.請求優先級 流能夠帶有一個31bit的優先級:
0:表示最高優先級
2的31次方-1 表示最低優先級。

服務端按優先級返回結果有利於高效利用底層鏈接,提升用戶體驗。
4.服務端推送
HTTP2.0增長了服務端推送功能,服務端能夠根據客戶端的請求,提早返回多個響應,推送額外的資源給客戶端。

HTTP 2.0 鏈接後,客戶端與服務器交換SETTINGS 幀,藉此能夠限定雙向併發的流的最大數量。所以,客戶端能夠限定推送流的數量,或者經過把這個值設置爲0 而徹底禁用服務器推送。
全部推送的資源都遵照同源策略。換句話說,服務器不能隨便將第三方資源推送給客戶端,而必須是通過雙方確認才行。
PUSH_PROMISE幀是服務端向客戶端有意推送資源的信號。
若是客戶端不須要服務端Push,可在SETTINGS幀中設定服務端流的值爲0,禁用此功能
PUSH_PROMISE幀中只包含預推送資源的首部。若是客戶端對PUSH_PROMISE幀沒有意見,服務端在PUSH_PROMISE幀後發送響應的DATA幀開始推送資源。若是客戶端已經緩存該資源,不須要再推送,能夠選擇拒絕PUSH_PROMISE幀。
PUSH_PROMISE必須遵循請求-響應原則,只能藉着對請求的響應推送資源。
幾點限制:
服務器必須遵循請求- 響應的循環,只能藉着對請求的響應推送資源
PUSH_PROMISE 幀必須在返回響應以前發送,以避免客戶端出現競態條件。


5.首部壓縮
HTTP1.x每一次通訊(請求/響應)都會攜帶首部信息用於描述資源屬性。HTTP2.0在客戶端和服務端之間使用「首部表」來跟蹤和存儲以前發送的鍵值對.首部表在鏈接過程當中始終存在,新增的鍵值對會更新到表尾,所以,不須要每次通訊都須要再攜帶首部。
HTTP2.0使用了首部壓縮技術,可以讓報頭更緊湊、更快速傳輸。HTTP 2.0關注的是首部壓縮,而咱們經常使用的gzip等是報文內容(body)的壓縮。
2、HTTP2.0的完整通訊過程
在兩端使用HTTP2.0通訊以前,必然存在協議協商的過程。
1.基於ALPN的協商過程
HTTPS 協商過程當中有一個環節會使用ALPN(應用層協議協商)。減小網絡延遲是HTTP 2.0 的關鍵條件,所以在創建HTTPS 鏈接時必定會用到ALPN協商。
支持HTTP 2.0的瀏覽器能夠在TLS會話層自發完成和服務端的協議協商以肯定是否使用HTTP 2.0通訊。其原理是TLS 1.2中引入了擴展字段,以容許協議的擴展,其中ALPN協議(Application Layer Protocol Negotiation, 應用層協議協商, 前身是NPN)用於客戶端和服務端的協議協商過程。

2.基於HTTP的協商過程
客戶端使用HTTP也能夠開啓HTTP 2.0通訊。只不過由於HTTP 1. 0和HTTP 2. 0都使用同一個 端口(80), 又沒有服務器是否支持HTTP 2. 0的其餘任何 信息,此時 客戶端只能使用HTTP Upgrade機制(OkHttp, nghttp2等組件都可實現,也能夠本身編碼完成)經過協調肯定適當的協議

3.完整通訊過程 (1)TCP鏈接創建
(2)TLS握手和HTTP2.0通訊過程
1)TLS握手
2)客戶端向服務端發送SETTINGS幀,約定配置
3)流量控制
4)客戶端向服務端發送HEADERS幀
5)服務端返回配置
6)DATA幀傳輸數據

3、發起新流
在發送應用數據以前,必須建立一個新流並隨之發送相應的元數據,好比流優先級、HTTP 首部等;
客戶端經過發送HEADERS幀來發起新流;
服務器經過發送 PUSH_PROMISE 幀來發起推送流。

4、發送應用數據
建立新流併發送HTTP 首部以後,接下來就是利用DATA 幀。應用數據能夠分爲多個DATA 幀,最後一幀要翻轉幀首部的END_STREAM 字段
HTTP 2.0 標準要求DATA 幀不能超過2的14次方-1(16383)字節。長度超過這個閥值的數據,就得分幀發送。
5、去掉對HTTP1.X的優化
每一個來源使用一個鏈接,HTTP 2.0 經過將一個TCP 鏈接的吞吐量最大化來提高性能。
去掉沒必要要的文件合併和圖片拼接:HTTP 2.0,不少小資源均可以並行發送
利用服務器推送:以前針對HTTP 1.x 而嵌入的大多數資源,均可以並且應該經過服務器推送來交付。

十5、HTTPS

15.1 HTTP的缺點

1.通訊使用明文(不加密),內容可能會被竊聽;
TCP/IP是可能被竊聽的網絡:按TCP/IP協議族的工做機制,通訊內容在全部線路上都有可能遭到窺視。
加密處理防止被竊聽,加密的對象以下:

(1)通訊的加密 經過和SSL(Secure Socket Layer,安全套接層)或TLS(Transport Layer Security,安全層傳輸協議)的組合使用,加密HTTP的通訊內容。用SSL創建安全通訊線路以後,就能夠在這條線路上進行HTTP通訊了。與SSL組合使用的HTTP稱爲HTTPS。
這種方式將整個通訊線路加密

(2)內容的加密 因爲HTTP協議中沒有加密機制,那麼就對HTTP協議傳輸的內容自己加密。
爲了作到有效的內容加密,前提是要求客戶端和服務器同時具有加密和解密機制。
該方式不一樣於將整個通訊線路加密處理,內容仍有被篡改的風險。
2.不驗證通訊方的身份,所以有可能遭遇假裝;
(1)任何人均可發起請求
HTTP協議不管是誰發送過來的請求都會返回響應,所以不確認通訊方,會存在如下隱患:
沒法肯定請求發送至目標的Web服務器是不是按真是意圖返回響應的那臺服務器,有多是已假裝的Web服務器。
沒法肯定響應返回到的客戶端是不是按照真實意圖接收響應的那個客戶端,有多是假裝的客戶端。
沒法肯定正在通訊的對方是否具有訪問權限,由於某些Web服務器上保存着重要的信息,只想發給特定用戶通訊的權限。
沒法判斷請求是來自何方、出自誰手
即便是無心義的請求也會照單全收,沒法阻止海量請求下的Dos攻擊(Denial of Service,拒絕服務攻擊)。
(2)查明對手的證書
SSL不只提供加密處理,還使用了一種被稱爲證書的手段,可用於肯定通訊方。
證書由值得信任的第三方機構頒發,用以證實服務器和客戶端是實際存在的。
使用證書,以證實通訊方就是意料中的服務器,對使用者我的來說,也減小了我的信息泄露的危險性。另外,客戶端持有證書便可完成我的身份的確認,也可用於對Web網站的認證環節。
3.沒法證實報文的完整性,因此有可能已遭遇篡改。
(1)接收到的內容可能有誤
在請求或響應送出以後直到對方接收以前的這段時間內,即便請求或響應的內容遭到篡改,也沒有辦法獲悉。
在請求或響應的傳輸途中,遭攻擊者攔截並篡改內容的攻擊稱爲中間人攻擊(Man-in-the-Middle attack)。
(2)如何防止篡改
僅靠HTTP確保完整性是很是困難的,便有賴於HTTPS來實現。SSL提供認證和加密處理及摘要功能。

15.2 HTTPS是如何加密數據的

把添加了加密、認證機制、完整性保護的HTTP稱爲HTTPS

HTTPS 並不是是應用層的一種新協議。只是 HTTP 通訊接口部分用SSL(Secure Socket Layer)和TLS(Transport Layer Security) 協議代替而已。
TLS的前身是SSL

一般,HTTP直接和TCP通訊,當使用SSL時,則演變成先和SSL通訊,再由SSL和TCP通訊了,簡言之,所謂HTTPS其實就是身披SSL協議這層外殼的HTTP
SSL協議使用通訊雙方的客戶證書以及CA根證書,容許客戶/服務器應用以一種不能被偷聽的方式通訊,在通訊雙方間創建起了一條安全的、可信任的通訊通道。
1.加密分爲對稱加密和非對稱加密(也叫公開密鑰加密)
(1)對稱加密的意思就是,加密數據用的密鑰,跟解密數據用的密鑰是同樣的。
1)對稱加密的優勢在於加密、解密效率一般比較高。速度快,對稱性加密一般在消息發送方須要加密大量數據時使用,算法公開、計算量小、加密速度快、加密效率高。
2)缺點在於,數據發送方、數據接收方須要協商、共享同一把密鑰,並確保密鑰不泄露給其餘人。此外,對於多個有數據交換需求的個體,兩兩之間須要分配並維護一把密鑰,這個帶來的成本基本是不可接受的。
(2)非對稱加密的意思就是,加密數據用的密鑰(公鑰),跟解密數據用的密鑰(私鑰)是不同的。
公鑰就是公開的密鑰,誰均可以查到;私鑰就是非公開的密鑰,通常是由網站的管理員持有。
公鑰與私鑰的聯繫:簡單的說就是,經過公鑰加密的數據,只能經過私鑰解開。經過私鑰加密的數據,只能經過公鑰解開。
2.公開密鑰存在問題
問題一:公鑰如何獲取;
問題二:數據傳輸僅單向安全(由於私鑰加密數據,公鑰也能解開,因此只是單向安全)
(1)對於公鑰如何獲取這個問題
這裏涉及兩個重要概念:證書、CA(證書頒發機構)
證書:能夠暫時把它理解爲網站的身份證。這個身份證裏包含了不少信息,其中就包含了上面提到的公鑰。當訪問相應網站時,他就會把證書發給瀏覽器;
證書來自於CA(證書頒發機構)
(2)證書可能存在的問題:


證書是僞造的:壓根不是CA頒發的
證書被篡改過:好比將XX網站的公鑰給替換了

數字簽名、摘要是證書防僞很是關鍵的武器。
「摘要」就是對傳輸的內容,經過hash算法計算出一段固定長度的串。而後,在經過CA的私鑰對這段摘要進行加密,加密後獲得的結果就是「數字簽名」。
明文 --> hash運算 --> 摘要 --> 私鑰加密 --> 數字簽名
數字簽名只有CA的公鑰纔可以解密。
證書格式,須要關注的有幾個點:

證書包含了頒發證書的機構的名字 -- CA
證書內容自己的數字簽名(用CA私鑰加密)
證書持有者的公鑰
證書籤名用到的hash算法

其中CA自己有本身的證書,稱爲根證書。
1)對於徹底僞造的證書
這種狀況對證書進行檢查

證書頒發的機構是僞造的:瀏覽器不認識,直接認爲是危險證書
證書頒發的機構是確實存在的,因而根據CA名,找到對應內置的CA根證書、CA的公鑰。用CA的公鑰,對僞造的證書的摘要進行解密,發現解不了。認爲是危險證書

2)篡改過的證書

檢查證書,根據CA名,找到對應的CA根證書,以及CA的公鑰。
用CA的公鑰,對證書的數字簽名進行解密,獲得對應的證書摘要AA
根據證書籤名使用的hash算法,計算出當前證書的摘要BB
對比AA跟BB,發現不一致--> 斷定是危險證書

15.3 HTTPS流程

1.客戶端發起HTTPS請求
2.服務端響應,下發證書(公開密鑰證書)
3.客戶端檢查證書,若是證書沒問題,那麼就生成一個隨機值,而後用證書(公鑰)對該隨機值進行加密。
4.將通過公鑰加密的隨機值發送到服務端(非對稱加密),之後客戶端和服務器的通訊就能夠經過這個隨機值進行加密解密了。
5.服務端用私鑰解密後,獲得了客戶端傳過來的隨機值,而後把內容經過該值進行對稱加密。
6.後期的數據傳輸都是基於該隨機值進行加密解密。


15.4 對於公鑰獲取這個問題

涉及到證書和CA(證書頒發機構)
證書可能存在的問題:1.證書是僞造的,壓根不是CA頒發的;
2.證書被篡改過
數字簽名和摘要是證書防僞很是關鍵的武器
明文--->hash算法--->摘要---->私鑰加密----->數字簽名
數字簽名只有CA的公鑰纔可以解密
CA證書自己有本身的證書,稱爲根證書。
(1)對於徹底僞造的證書
這種狀況對證書進行檢查

證書頒發的機構是僞造的:瀏覽器不認識,直接認爲是危險證書
證書頒發的機構是確實存在的,因而根據CA名,找到對應內置的CA根證書、CA的公鑰。用CA的公鑰,對僞造的證書的數字簽名進行解密,發現解不了。認爲是危險證書

(2)篡改過的證書

檢查證書,根據CA名,找到對應的CA根證書,以及CA的公鑰。
用CA的公鑰,對證書的數字簽名進行解密,獲得對應的證書摘要AA
根據證書籤名使用的hash算法,計算出當前證書的摘要BB
對比AA跟BB,發現不一致--> 斷定是危險證書

15.5 客戶端證書

HTTPS中還能夠使用客戶端證書,以客戶端證書進行客戶端認證,證實服務器正在通訊的對方始終是預料以內的客戶端。想獲取證書時,用戶得自行安裝客戶端證書。
現狀是,安全性極高的認證機構可頒發客戶端證書但僅用於特殊用途的業務,好比網上銀行等。

15.6 HTTPS問題

1.與純文本相比,加密通訊會消耗更多的CPU及內存資源
因爲HTTPS還須要作服務器、客戶端雙方加密及解密處理,所以會消耗CPU和內存等硬件資源。
和HTTP通訊相比,SSL通訊部分消耗網絡資源,而SSL通訊部分,由由於要對通訊進行處理,因此時間上又延長了。
SSL慢分兩種,一種是指通訊慢;另外一種是指因爲大量消耗CPU及內存等資源,致使處理速度變慢。
2.購買證書須要開銷。

十6、WebSocket



16.1 WebSocket API

1.WS和WSS WebSocket資源URL採用了自定義模式,ws表示純文本通訊,wss表示使用加密信道通訊(TCP+TLS)
WebSocket的主要目的,是在瀏覽器中的應用與服務器之間提供優化的、雙向通訊機制。但是,WebSocket的鏈接協議也能夠用於瀏覽器以外的場景,能夠經過非HTTP協商機制交換數據。
2.接收文本和二進制數據
WebSocket通訊只涉及消息,應用代碼無需擔憂緩存、解析、重建接收到的數據。好比,服務器發來了一個1MB的淨荷,應用的onmessage回掉只會在客戶端接收到所有數據時纔會被調用。
淨荷能夠是文本也能夠是二進制數據。
瀏覽器接收到新消息後,若是是文本數據,會自動將其轉換成DOMString對象,若是是二進制數據或Blob對象(Blob對象通常表明一個不可變的文件對象或原始數據。若是你不須要修改它或者不須要把它切分紅更小的塊,這種格式是理想的,若須要處理則選擇ArrayBuffer更合適),會直接將其轉交給應用。惟一能夠多餘設置的,就是告訴瀏覽器把接收到的二進制數據轉換成ArrayBuffer而非Blob

➊ 若是接收到二進制數據,將其強制轉換成 ArrayBuffer
3.發送文本和二進制數據
客戶端就能夠隨時發送或接收 UTF-8 或二進制消息
這裏的send()方法是異步的:提供的數據會在客戶端排隊,而函數則當即返回。特別是傳輸大文件的時候,千萬別由於返回快,就認爲數據已經發送出去了。能夠經過bufferedAmount屬性來監控瀏覽器中排隊的數據量。ws.bufferedAmount
4.子協議協商
WebSocket協議對每條消息的格式事先不做任何假設:僅用一位標記消息是文本仍是爲二進制,以便客戶端和服務器有效地解碼數據,而除此以外的消息內容就是未知的。
此外,與 HTTP 或 XHR 請求不一樣——它們是經過每次請求和響應的 HTTP 首部來溝通元數據, WebSocket 並無等價的機制。所以,若是須要溝通關於消息的元數據,客戶端和服務器必須達成溝通這一數據的子協議。
WebSocket爲此提供了一個簡單便捷的子協議協商API。客戶端能夠在初次鏈接握手時,告訴服務器本身支持哪一種協議:

WebSocket 構造函數能夠接受一個可選的子協議名字的數組,經過這個數組,客戶端能夠向服務器通告本身可以理解或但願服務器接受的協議。這個協議數組會發送給服務器,服務器能夠從中挑選一個。
若是子協議協商成功,就會觸發客戶端的 onopen 回調,應用能夠查詢 WebSocket 對象上的 protocol 屬性,從而得知服務器選定的協議。另外一方面,服務器若是不支持客戶端聲明的任何一個協議,則 WebSocket 握手是不完整的,此時會觸發 onerror 回調,鏈接斷開。


16.2 WebSocket協議

WebSocket通訊協議包含兩個高層組件:開放性HTTP握手用於協商鏈接參數,二進制消息分幀機制用於支持低開銷的基於消息的文本和二進制數據傳輸。
1.二進制分幀層
WebSocket使用了自定義的二進制分幀格式,把每一個消息切分紅一或多個幀,發送到目的地以後再組裝起來,等到接收到完整的消息後再通知接收端。

幀:最小的通訊單位,包含可變長度的幀首部和淨荷部分
消息:一系列幀
FIN:表示當前幀是否是消息的最後一幀。
操做碼(4位):表示被傳輸幀的類型:文本(1),二進制(2)
掩碼位表示淨荷是否有掩碼(只適用於客戶端發送給服務器的消息)。
算下來,服務器發送的每一個WebSocket幀會產生2~10字節的分幀開銷。而客戶端必須發送掩碼鍵,這又會增長4字節,結果就是6~14字節的開銷。除此以外,沒有其餘元素據。
2.WebSocket的多路複用及隊首阻塞
WebSocket很容易發生隊首阻塞的狀況:消息可能會被分紅一個或多個幀,但不一樣消息的幀不能交錯發送,由於沒有與HTTP2.0分幀機制中「流ID」對等的字段。
WebSocket不支持多路複用,還意味着每一個WebSocket鏈接都須要一個專門的TCP鏈接。對於HTTP1.x而言,因爲瀏覽器針對每一個來源有鏈接數量限制,所以可能會致使問題。
雖然經過HTTP2.0傳輸WebSocket幀的官方規範還沒有發佈,但相對來講容易不少。由於HTTP2.0內置了流的多路複用,只要經過HTTP2.0的分幀機制來封裝WebSocket幀,多個WebSokcet鏈接就能夠在一個會話中傳輸。
3.協議擴展
(1)多路複用擴展
這個擴展能夠將WebSocket的邏輯鏈接獨立出來,實現共享底層的TCP鏈接。
(2)壓縮擴展
給WebSocket協議增長了壓縮功能。
如前所述,每一個 WebSocket 鏈接都須要一個專門的 TCP 鏈接,這樣效率很低。多路複用擴展解決了這個問題。它使用「信道 ID」擴展每一個 WebSocket 幀,從而實現多個虛擬的 WebSocket 信道共享一個 TCP 鏈接。相似地,基本的 WebSocket 規範沒有壓縮數據的機制或建議,每一個幀中的淨荷就是應用提供的淨荷。雖然這對優化的二進制數據結構不是問題,但除非應用實現本身的壓縮和解壓縮邏輯,不然不少狀況下都會形成傳輸載荷過大的問題。實際上,壓縮擴展就至關於 HTTP 的傳輸編碼協商。
要使用擴展,客戶端必須在第一次的Upgrade握手中通知服務器,服務器必須選擇並確認要在商定鏈接中使用的擴展。
4.HTTP升級協商
在交換數據以前,客戶端必須與服務器協商適當的參數以創建鏈接。
利用HTTP完成握手有幾個好處。首先,讓WebSocket與現有HTTP基礎設施兼容:WebSocket服務器能夠運行在80和443端口上,這一般是對客戶端惟一開放的端口。其次,讓咱們能夠重用並擴展HTTP的Upgrade流,爲其添加自定義的WebSocket
首部,以完成協商。

與瀏覽器中客戶端發起的任何鏈接同樣,WebSocket請求也必須遵照同源策略:瀏覽器會自動在升級握手請求中追加Origin首部,遠程服務器可能使用CORS判斷接受或拒絕跨源請求。要完成握手,服務器必須返回一個成功的「Switching Protocols」(切換協議)響應,並確認選擇了客戶端發送的哪一個選項:

若是握手成功,該鏈接就能夠用做雙向通訊信道交換WebSocket消息。今後之後,客戶端與服務器之間不會再發生HTTP通訊,一切由WebSocket協議接管。


16.3 WebSocket使用場景及性能

1.請求和響應流
WebSocket是惟一一個能經過同一個TCP鏈接實現雙向通訊的機制,客戶端和服務器隨時能夠交換數據。
2.消息開銷
應用消息會被拆分爲一或多個幀,每一個幀會添加2~14字節的開銷。並且,因爲分幀是按照自定義的二進制格式完成的, UTF-8 和二進制應用數據能夠有效地經過相同的機制編碼。
(1)SSE會給每一個消息添加5個字節,但僅限於UTF-8內容
(2)HTTP 1.x 請求(XHR 及其餘常規請求)會攜帶 500~800 字節的 HTTP 元數據,加上 cookie
(3)HTTP 2.0 壓縮 HTTP 元數據,這樣能夠顯著減小開銷
3.數據效率及壓縮
除非應用經過細緻優化本身的二進制淨荷實現本身的壓縮邏輯,同時也針對文本消息實現本身的壓縮邏輯,不然傳輸數據過程當中必定會產生很大的字節開銷!
4.自定義應用協議

16.4 圖解HTTP上解釋

WebSocket技術主要是爲了解決Ajax和Comet裏XMLHttpRequest附帶的缺陷所引發的問題。
WebSocket是創建在HTTP基礎上的協議,所以鏈接的發起方仍然是客戶端。
Websocket只須要一次HTTP握手,因此說整個通信過程是創建在一次鏈接/狀態中,也就避免了HTTP的非狀態性,服務端會一直知道你的信息,直到你關閉請求
(1)WebSocket的主要特色
1)推送功能
支持由服務器向客戶端推送數據的推送功能。
2)減小通訊量
只要創建起WebSocket鏈接,就但願一直保持鏈接狀態。和HTTP相比,不但每次鏈接時的總開銷減小,並且因爲WebSokcet的首部信息很小,通訊量也相應減小了;
(2)握手請求
爲了實現WebSocket通訊,在HTTP鏈接創建以後,須要完成一次「握手」的步驟。
爲了實現WebSocket通訊,須要用到HTTP的Upgrade首部字段,告知服務器通訊協議發生改變,以達到握手的目的。

Sec-WebSocket-Key:記錄握手須要的鍵值;
Sec-WebSocket-Protocol:記錄使用的子協議;

(3)握手響應
對於以前的請求,返回狀態碼101 Switching Protocols的響應。成功握手確立WebSocket鏈接以後,通訊時再也不使用HTTP的數據幀,而採用WebSockte獨立的數據幀;

Sec-WebSocket-Accept:該字段值是由握手請求中的Sec-WebSocket-Key的字段值生成的;



16.5 WebSocket優勢(對比參照HTTP協議)

https://yq.aliyun.com/articles/633679?spm=a2c4e.11153940.0.0.5e293dd6CNm3ZH (1)支持雙向通訊,實時性更強;
(2)更好的二進制支持;
(3)較少的控制開銷:
鏈接建立後,ws客戶端、服務端進行數據交換時,協議控制的數據包頭部較小。在不包含頭部的狀況下,服務端到客戶端的包頭只有2~10字節(取決於數據包長度),客戶端到服務端的的話,須要加上額外的4字節的掩碼。而HTTP協議每次通訊都須要攜帶完整的頭部;
(4)支持擴展:
ws協議定義了擴展,用戶能夠擴展協議,或者實現自定義的子協議(好比支持自定義壓縮算法等)。

16.6 如何創建鏈接

WebSocket複用了HTTP的握手通道。具體指的是,客戶端經過HTTP請求與WebSocket服務端協商升級協議。協議升級完成後,後續的數據交換則遵守WebSocket的協議。
1.客戶端:申請協議升級
首先,客戶端發起協議升級請求。能夠看到,採用的是標準的HTTP報文格式,且只支持GET方法 Connection: Upgrade:表示要升級協議
Upgrade: websocket:表示要升級到websocket協議。
Sec-WebSocket-Version: 13:表示websocket的版本。若是服務端不支持該版本,須要返回一個Sec-WebSocket-Versionheader,裏面包含服務端支持的版本號。
Sec-WebSocket-Key:與後面服務端響應首部的Sec-WebSocket-Accept是配套的,提供基本的防禦,好比惡意的鏈接,或者無心的鏈接。
2.服務端:響應協議升級
返回狀態碼101表示協議切換

16.7 數據幀格式

客戶端、服務器數據的交換,離不開數據幀格式的定義。
WebSocket客戶端、服務端通訊的最小單位是幀,由一個或多個幀組成一條完整的消息。
發送端:將消息切割成多個幀,併發送給服務端;
接收端:接收消息幀,並將關聯的幀從新組裝成完整的消息。
幀內容見上面二小結

16.8 數據傳遞

一旦WebSocket客戶端、服務端創建鏈接後,後續的操做都是基於數據幀的傳遞。WebSocket根據opcode來區分操做的類型。好比0x8表示斷開鏈接,0x0-0x2表示數據交互。
1.數據分片
WebSocket的每條消息可能被切分紅多個數據幀。當WebSocket的接收方收到一個數據幀時,會根據FIN的值來判斷,是否已經收到消息的最後一個數據幀。
FIN=1表示當前數據幀爲消息的最後一個數據幀,此時接收方已經收到完整的消息,能夠對消息進行處理。FIN=0,則接收方還須要繼續監聽接收其他的數據幀。
opcode在數據交換的場景下,表示的是數據的類型。0x01表示文本,0x02表示二進制。而0x00比較特殊,表示延續幀(continuation frame),顧名思義,就是完整消息對應的數據幀還沒接收完。

16.9 鏈接保持+心跳

WebSocket爲了保持客戶端、服務端的實時雙向通訊,須要確保客戶端、服務端之間的TCP通道保持鏈接沒有斷開。
有些場景,客戶端、服務端雖然長時間沒有數據往來,但仍須要保持鏈接,這個時候能夠採用心跳來實現:
發送方->接收方:ping
接收方->發送方:pong
ping、pong的操做,對應的是WebSocket的兩個控制幀,opcode分別是0x九、0xA
例如:ws.ping('', false, true);

16.10 Sec-WebSocket-Key/Accept的做用

Sec-WebSocket-Key/Sec-WebSocket-Accept在主要做用在於提供基礎的防禦,減小惡意鏈接、意外鏈接。

16.11 數據掩碼的做用

WebSocket協議中,數據掩碼的做用是加強協議的安全性。但數據掩碼並非爲了保護數據自己(由於算法自己是公開的,運算也不復雜),而是爲了防止早期版本的協議中存在的代理緩存污染攻擊等問題。

十7、狀態碼301和302的區別

(1)什麼是301重定向?
301重定向/跳轉通常,表示本網頁永久性轉移到另外一個地址。
301是永久性轉移(Permanently Moved),SEO(搜索引擎優化)經常使用的招式,會把舊頁面的PR(永久居留)等信息轉移到新頁面;
(2)什麼是302重定向?
302重定向表示臨時性轉移(Temporarily Moved),當一個網頁URL須要短時間變化時使用。
(3)301重定向與302重定向的區別
301重定向是永久的重定向,搜索引擎在抓取新內容的同時也將舊的網址替換爲重定向以後的網址。
302重定向是臨時的重定向,搜索引擎會抓取新的內容而保留舊的網址。由於服務器返回302代碼,搜索引擎認爲新的網址只是暫時的。

十8、強緩存引發問題的解決方案(如何更新網站資源)

存在問題:發佈時資源更新問題,更新了資源,可是用戶每次請求時依然從緩存中獲取原來的資源,除非用戶清除或者強刷新,不然看不到最新的效果。
一、利用304定向重定向,讓瀏覽器本地緩存即協商緩存。
缺點:協商緩存仍是須要和瀏覽器通訊一次。
二、強制瀏覽器使用本地緩存,不和服務器通訊。
缺點:沒法更新緩存。
三、經過更新頁面中引用的資源路徑,讓瀏覽器主動放棄緩存,加載新資源。例如在文件名稱後面增長一個版本號,下次上線時更改版本號。
缺點:當有多個靜態緩存文件,只有一個文件更改時,卻須要更新全部文件。

採用數據摘要算法

想要解決這個問題:考慮到讓url的修改與文件內容相關聯即只有文件內容變化時,纔會致使相應的url的變動,從而實現文件級別的精確緩存控制。
爲了進一步提高網站性能,會把靜態資源和動態網頁分集羣部署,靜態資源會被部署到CDN節點上,網頁中引用的資源也會變成對應的部署路徑。當我要更新靜態資源的時候,同時也會更新html中的引用。若此次發佈,同時改了頁面結構和樣式,也更新了靜態資源對應的url地址,如今要發佈代碼上線,我們是先上線頁面,仍是先上線靜態資源?

先部署頁面,再部署資源:在兩者部署的時間間隔內,若是有用戶訪問頁面,就會在新的頁面結構中加載舊的資源,而且把這個舊版本的資源當作新版本緩存起來,其結果就是:用戶訪問到了一個樣式錯亂的頁面,除非手動刷新,不然在資源緩存過時以前,頁面會一直執行錯誤。
先部署資源,再部署頁面:在部署時間間隔以內,有舊版本資源本地緩存的用戶訪問網站,因爲請求的頁面是舊版本的,資源引用沒有改變,瀏覽器將直接使用本地緩存,這種狀況下頁面展示正常;但沒有本地緩存或者緩存過時的用戶訪問網站,就會出現舊版本頁面加載新版本資源的狀況,致使頁面執行錯誤,但當頁面完成部署,這部分用戶再次訪問頁面又會恢復正常了。

上述先部署誰都有問題,這是由於採用的是覆蓋式發佈,用 待發布資源 覆蓋 已發佈資源,就有這種問題。解決它也好辦,就是實現 非覆蓋式發佈。
大公司的靜態資源優化方案:
1.配置超長時間的本地緩存 —— 節省帶寬,提升性能
2.採用內容摘要做爲緩存更新依據 —— 精確的緩存控制
3.靜態資源CDN部署 —— 優化網絡請求
4.更新資源發佈路徑實現非覆蓋式發佈 —— 平滑升級

十9、滑動窗口原理

19.1 TCP滑動窗口(發送窗口和接收窗口)

TCP滑動窗口主要有兩個做用,一是提供TCP的可靠性,二是提供TCP的流控特性(TCP的滑動窗口是動態的)。同時滑動窗口機制還體現了TCP面向字節流的設計思路。
TCP的Window是一個16bit位字段,它表明的是窗口的字節容量,也就是TCP的標準窗口最大爲2^16 - 1 = 65535個字節。
1.對於TCP會話的發送方,任什麼時候候在其發送緩存內的數據均可以分爲4類,「已經發送並獲得對端ACK的」,「已經發送但還未收到對端ACK的」,「未發送但對端容許發送的」,「未發送且對端不容許發送」。「已經發送但還未收到對端ACK的」和「未發送但對端容許發送的」這兩部分數據稱之爲發送窗口(中間兩部分)。

當收到接收方新的ACK對於發送窗口中後續字節的確認是,窗口滑動,滑動原理以下圖。

當收到ACK=36時窗口滑動
2.對於TCP的接收方,在某一時刻在它的接收緩存內存有3種。「已接收」,「未接收準備接收」,「未接收並未準備接收。其中「未接收準備接收」稱之爲接收窗口。
3.發送窗口和接收窗口關係
TCP是雙工的協議,會話的雙方均可以同時接收、發送數據。TCP會話的雙方都各自維護一個」發送窗口「和一個」接收窗口「。其中各自的」接收窗口「大小取決於應用、系統、硬件的限制(TCP傳輸速率不能大於應用的數據處理速率)。各類的」發送窗口「則要求取決於對端通告的」接收窗口「,要求相同。
4.滑動窗口實現面向流的可靠性
最基本的傳輸可靠性來源於」確認重傳「機制。
TCP的滑動窗口的可靠性也是創建在」確認重傳「基礎上的。
發送窗口只有收到對端對於本段發送窗口內字節的ACK確認,纔會移動發送窗口的左邊界。
接收窗口只有在前面全部的段都確認的狀況下才會移動左邊界。當在前面還有字節未接收但收到後面字節的狀況下,窗口不會移動,並不對後續字節確認。以此確保對端會對這些數據重傳。


19.2 TCP協議上的網絡協議分類

目前創建在TCP協議上的網絡協議特別多,有telnet,ssh,有ftp,有http等等。這些協議又能夠根據數據吞吐量來大體分紅兩大類:
(1)交互數據類型,例如telnet,ssh,這種類型的協議在大多數狀況下只是作小流量的數據交換,好比說按一下鍵盤,回顯一些文字等等。
(2)數據成塊類型,例如ftp,這種類型的協議要求TCP能儘可能的運載數據,把數據的吞吐量作到最大,並儘量的提升效率。

19.3 滑動窗口協議相關術語

滑動窗口本質上是描述接受方的TCP數據報緩衝區大小的數據,發送方根據這個數據來計算本身最多能發送多長的數據。若是發送發收到接收方的窗口大小爲0的TCP數據報,那麼發送方將中止發送數據,等到接收方發送窗口大小不爲0的數據報的到來。
關於滑動窗口協議介紹了三個術語,分別是:

窗口合攏:當窗口從左邊向右邊靠近的時候,這種現象發生在數據被髮送和確認的時候。
窗口張開:當窗口的右邊沿向右邊移動的時候,這種現象發生在接受端處理了數據之後。
窗口收縮:當窗口的右邊沿向左邊移動的時候,這種現象不常發生

19.4 舉一個例子來講明一下滑動窗口的原理

TCP並非每個報文段都會回覆ACK的,可能會對兩個報文段發送一個ACK,也可能會對多個報文段發送1個ACK【累計ACK】,好比說發送方有1/2/3 3個報文段,先發送了2,3 兩個報文段,可是接收方指望收到1報文段,這個時候2,3報文段就只能放在緩存中等待報文1的空洞被填上,若是報文1,一直不來,報文2/3也將被丟棄,若是報文1來了,那麼會發送一個ACK對這3個報文進行一次確認。
舉一個例子來講明一下滑動窗口的原理:
1. 假設32~45 這些數據,是上層Application發送給TCP的,TCP將其分紅四個Segment來發往internet
2. seg1 32~34 seg3 35~36 seg3 37~41 seg4 42~45 這四個片斷,依次發送出去,此時假設接收端之接收到了seg1 seg2 seg4
3. 此時接收端的行爲是回覆一個ACK包說明已經接收到了32~36的數據,並將seg4進行緩存(保證順序,產生一個保存seg3 的hole)
4. 發送端收到ACK以後,就會將32~36的數據包從發送並無確認切到發送已經確認,提出窗口,這個時候窗口向右移動
5. 假設接收端通告的Window Size仍然不變,此時窗口右移,產生一些新的空位,這些是接收端容許發送的範疇
6. 對於丟失的seg3,若是超過必定時間,TCP就會從新傳送(重傳機制),重傳成功會seg3 seg4一塊被確認,不成功,seg4也將被丟棄
就是不斷重複着上述的過程,隨着窗口不斷滑動,將真個數據流發送到接收端,實際上接收端的Window Size通告也是會變化的,接收端根據這個值來肯定什麼時候及發送多少數據,從對數據流進行流控。原理圖以下圖所示:


19.5 滑動窗口動態調整

主要是根據接收端的接收狀況,動態去調整Window Size,而後來控制發送端的數據流量
客戶端不斷快速發送數據,服務器接收相對較慢,看下實驗的結果
a. 包175,發送ACK攜帶WIN = 384,告知客戶端,如今只能接收384個字節
b. 包176,客戶端果然只發送了384個字節,Wireshark也比較智能,也宣告TCP Window Full
c. 包177,服務器回覆一個ACK,並通告窗口爲0,說明接收方已經收到全部數據,並保存到緩衝區,可是這個時候應用程序並無接收這些數據,致使緩衝區沒有更多的空間,故通告窗口爲0, 這也就是所謂的零窗口,零窗口期間,發送方中止發送數據
d. 客戶端察覺到窗口爲0,則再也不發送數據給接收方
e. 包178,接收方發送一個窗口通告,告知發送方已經有接收數據的能力了,能夠發送數據包了
f. 包179,收到窗口通告以後,就發送緩衝區內的數據了.

總結一點,就是接收端能夠根據本身的情況通告窗口大小,從而控制發送端的接收,進行流量控制


二10、Chrome中的from memory cache與from disk cache

1. 在瀏覽器開發者工具的Network的Size列會出現的三種狀況

  • from memory cache

  • from disk cache

  • 資源自己大小(好比:13.6K)

2. 三級緩存原理

先查找內存,若是內存中存在,從內存中加載;
若是內存中未查找到,選擇硬盤獲取,若是硬盤中有,從硬盤中加載;
若是硬盤中未查找到,那就進行網絡請求;
加載到的資源緩存到硬盤和內存;

3. HTTP狀態碼及區別

  • 200 form memory cache

不訪問服務器,通常已經加載過該資源且緩存在了內存當中,直接從內存中讀取緩存。瀏覽器關閉後,數據將不存在(資源被釋放掉了),再次打開相同的頁面時,不會出現from memory cache。

  • 200 from disk cache

不訪問服務器,已經在以前的某個時間加載過該資源,直接從硬盤中讀取緩存,關閉瀏覽器後,數據依然存在,此資源不會隨着該頁面的關閉而釋放掉下次打開仍然會是from disk cache。

  • 200 大小(如3.4k)

訪問服務器,size顯示爲實際資源的大小

  • 304 Not Modified

訪問服務器,發現數據沒有更新,服務器返回此狀態碼。而後從緩存中讀取數據。這種在請求頭中有兩個請求參數:If-Modified-Since 和 If-None-Match。

狀態碼 類型 說明
200 form memory cache 不請求網絡資源,資源在內存當中
200 form disk ceche 不請求網絡資源,在磁盤當中
200 資源大小數值 從服務器下載最新資源
304 報文大小 請求服務端發現資源沒有更新,使用本地資源

以上是chrome在請求資源是最多見的兩種http狀態碼,因而可知樣式表通常在磁盤中,不會緩存到內存中去,由於css樣式加載一次便可渲染出網頁。可是腳本卻可能隨時會執行,若是腳本在磁盤當中,在執行該腳本須要從磁盤中取到內存當中來,這樣的IO開銷是比較大的,有可能會致使瀏覽器失去響應。

歡迎你們關注公衆號(回覆「nginx」獲取本節的思惟導圖,回覆「書籍」獲取大量前端學習資料,回覆「前端視頻」獲取大量前端教學視頻)


本文分享自微信公衆號 - 執鳶者(gh_4918fcc10eab)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索