前端瀏覽器網路系列進階(本地儲存,快取,網路,協議,安全)
前言
前端眼裡只有 Js, Vue,React, Node 嘛 ?
不 !
答案很明顯,現在的前端真的很強大,很複雜 ......
- 要會 html , css ,Js
- 緊跟著用框架呀 Jquery , bootstarp ,angularJs.1x.2x
- 很不巧 Vue 和 React 成為了主流
- 小程式悄然而生
- 跨平臺能行嘛 ? React Native , flutter
- 放棄伺服器端吧 Node 蹦出來了
- ......
再加上各種UI
框架,構建工具,前端的方向也算是四面八方, 我的天吶,痛苦 !
可是有一個知識點,在前端領域裡邊是必要的,瀏覽器
,關於瀏覽器知識,在如今的前端中也顯的尤為重要了,面試中頻繁被問及到,各種本地儲存,快取,網路,Http, Tcp/IP, 安全 等等,今天就跟我一起來學習一下瀏覽器相關知識
瀏覽器核心和渲染引擎
常見的瀏覽器核心有哪些
- Trident核心:IE,360,搜狗瀏覽器等。[又稱MSHTML]
- Presto核心:Opera7及以上。[Opera核心原為:Presto,現為:Blink;]
- Webkit核心:Safari,Chrome等。[ Chrome的Blink(WebKit的分支)]
為什麼我們需要知道一些基本的瀏覽器核心 ? 因為所有網頁瀏覽器、電子郵件客戶端以及其它需要顯示網路內容的應用程式都需要核心
瀏覽器渲染引擎有人說是 Css 引擎和 Js 引擎,其實具體點應該是渲染引擎和Js引擎,為什麼這麼說,因為瀏覽器在渲染一個網頁時,一般有三步
- 瀏覽器通過 HTMLParser 把 HTML 解析成 DOM Tree (俗稱DOM樹)。
- 瀏覽器通過 CSSParser 把 CSS 解析成 CSS Rule Tree(俗稱CSSOM樹)。
- 瀏覽器將 JavaScript 通過 DOM API 或者 CSSOM API 將 JS 程式碼解析並應用到佈局中,根據 DOM 樹和 CSSOM 樹來構造 Render Tree(Rander 樹)
最終的 Rander 樹就是整個頁面的文件結構抽象表示,然後按要求呈現響應的結果,所以結合這三步來分析,單純的 Css 渲染引擎從字面的意思上來講,並不能完全表達前兩步
- 渲染引擎
- Js引擎
渲染引擎:主要負責取得網頁的內容(HTML、XML、影象等等)、以及計算網頁的顯示方式,然後會輸出至瀏覽器,瀏覽器的核心的不同對於網頁的語法解釋會有不同,所以渲染的效果也不相同
JS引擎:主要負責解析和執行javascript程式碼來實現網頁的動態效果
本地儲存
- cookie
- sessionStorage
- localStorage
通過一個表格來對比一下
特性 | cookie | localStorage | sessionStorage |
---|---|---|---|
生命週期 | 一般由伺服器生成,可以設定過期時間 | 持久儲存 | 當前會話層儲存,關閉即清除 |
資料儲存大小 | 4K | 5M | 5M |
是否跨域 | 同源 http 請求中攜帶 , 預設不允許跨域 ,跨域需要設定withCredentials = true ,伺服器端需要允許 |
預設不允許跨域,可以使用 postMessage 解決 | cros |
儲存位置 | 伺服器端,每次請求會攜帶存放在 header 中 | 硬碟 | 記憶體 |
關於 cookie 部分屬性還需要注意一下安全性
- value 如果用於儲存使用者登入狀態,應該將該值加密
- http-only 不能通過 Js 訪問 Cookie,減少 XSS攻擊
- secure 只能在協議為 HTTPS 的請求中攜帶
- same-site 規定瀏覽器不能在跨域請求中攜帶 Cookie,減少 CSRF 攻擊
瀏覽器快取
簡單來說,瀏覽器快取其實就是瀏覽器把HTTP獲取的資源儲存在本地的一種行為
快取的優先順序
- 先在記憶體中查詢
- 如果記憶體中不存在,則在硬碟中查詢
- 如果硬碟中也沒有,那麼就進行網路請求
- 請求獲取的資源快取到硬碟和記憶體
快取分類
- 強快取
- 協商快取
先來捋一捋邏輯
- 當客戶端請求某個資源時,會先根據這個資源的 http header 判斷它是否命中強快取,如果命中,則直接從本地獲取快取資源,不會發請求到伺服器
- 當沒有命中強快取時,客戶端會發送請求到伺服器,伺服器通過 request header 驗證這個資源是否命中協商快取,如果命中,伺服器將返回 304,告訴客戶端從快取中獲取
- 當協商快取也沒命中時,伺服器就會將資源返回客戶端
- 當 ctrl+f5 強制重新整理網頁時,直接從伺服器載入,跳過強快取和協商快取
- 當 f5 重新整理網頁時,跳過強快取,但是會檢查協商快取
強快取
- Expires(是 http1.0 時的規範,值為一個絕對時間的 GMT 格式的時間字串,代表快取資源的過期時間)
- Cache-Control:max-age(是 http1.1的規範,強快取利用其 max-age 值來判斷快取資源的最大生命週期,它的值單位為秒)
Cache-Control 還有一些常用其它屬性:
- no-cache:需要進行協商快取,傳送請求到伺服器確認是否使用快取。
- no-store:禁止使用快取,每一次都要重新請求資料。
- public:可以被所有的使用者快取,包括終端使用者和CDN等中間代理伺服器。
- private:只能被終端使用者的瀏覽器快取,不允許CDN等中間代理伺服器對其快取。
Cache-Control 與 Expires 可以在服務端配置同時啟用,同時啟用的時候 Cache-Control 優先順序高
強快取缺點
快取過期之後,不管資源有沒有發生改變,都會重新發請求獲取資源,而我們希望是在資原始檔沒有變化的情況下,即使過期了也不重新獲取資源,繼續使用舊資源,所以就有了協商快取
協商快取
- Last-Modified / If-Modified-Since
Last-Modified 值為資源最後更新時間GMT 格式的時間
,隨服務端 response 返回, 當瀏覽器再次請求該資源時,request 請求頭中會包含 If-Modified-Since,該值為快取之前返回的 Last-Modified,伺服器收到 If-Modified-Since 後,根據資源的最後修改時間判斷是否命中協商快取
- ETag / If-None-Match
ETag 表示資源內容的唯一標識一串數字碼
,隨伺服器端 response 返回,伺服器通過比較請求頭部的 If-None-Match 與當前資源的 ETag 是否一致來判斷資源是否在兩次請求之間有過修改,如果沒有修改,則命中協商快取
有了 Last-Modified / If-Modified-Since 為什麼還需要 ETag / If-None-Match ?
因為如果本地打開了快取檔案,即使沒有對檔案進行修改或者在一定週期內做了修改又改了回來,結果都會造成 Last-Modified 被修改,伺服器端不能命中快取
結論
- 強快取優先順序高與協商快取
- 只要使用快取,伺服器均不會返回資源
- 強快取不會發送請求到伺服器
- 協商快取會發送請求到服務起
Http 網路請求型別
- Get: 傳送請求,獲取伺服器資料
- Post:向URL指定的資源提交資料
- Put:向伺服器提交資料,以修改資料
- Head:請求頁面的首部,獲取資源的元資訊
- Delete:刪除伺服器上的某些資源。
- Connect:建立連線隧道,用於代理伺服器;
- Options:列出可對資源實行的請求方法,常用於跨域
常見 Get 和 Post 區別
- Get 把引數包含在 URL 中,用 & 符號連線起來,POST 則是通過 request body 傳遞引數
- Get 請求會被主動快取 Cache, POST 請求不會,除非手動設定
- Post 比 Get 相對安全些,Get 請求在瀏覽器支援無感回退, Post 則會再次請求
- Get 請求引數會被完整保留在瀏覽歷史記錄裡,Post 中的引數不會被保留
- Get 請求在URL中傳送的引數是有長度限制的,Post 則沒有限制
- Get 請求只能使用 URL 編碼,Post 可以使用其它型別編碼
網路請求狀態碼
基本分為5類
- 1xx (資訊性狀態碼)接受的請求正在處理
- 2xx (成功狀態碼) 請求正常處理完畢
- 3xx (重定向) 需要進行附加操作以完成請求
- 4xx (客戶端錯誤) 客戶端請求出錯,伺服器無法處理請求
- 5xx (伺服器錯誤) 伺服器處理請求出錯
常見狀態碼:
- 200 請求成功,表示正常返回資訊
- 301 永久重定向,會快取,表示該請求 URL 永久發生了變化,此後以新的 URL 為準
- 302 臨時重定向,不會快取,表示本次請求 URL 臨時有變
- 304 常見於 Get 方法使用了協商快取,伺服器滿足條件返回的狀態碼
- 400 請求錯誤
- 401 需要認證,一般指沒有許可權,常見於需要 Token
- 403 伺服器禁止訪問
- 404 找不到與請求 URL 匹配的資源
- 500 常見的伺服器端錯誤
- 503 表示伺服器負載,無法處理請求
Http1.0, Http1.1, Http2.0 區別
Http 1.0
- HTTP 1.0 規定瀏覽器與伺服器只保持短連線,瀏覽器的每次請求都需要與伺服器建立一個TCP連線,伺服器完成請求處理後即斷開TCP連線。它也可以強制開啟長連結,例如設定
Connection: keep-alive
欄位
Http 1.1
- 引入了長連線,同時使用了管道機制(pipelining),在同一個TCP連線裡面,客戶端可以同時傳送多個請求(
Http管道機制是將多個Http請求(request)批量提交的技術,在傳送過程中不需等待服務端的迴應,並且只有 GET 和 HEAD 等請求方式可以進行管線化
) - 快取處理,引入了
Cache-Control
、Etag/If-None-Match
等 - 新增了一些錯誤狀態響應碼
Http 2
- 採用了多路複用,即在一個連線裡,客戶端和瀏覽器都可以同時傳送多個請求或迴應,而且不用按照順序一一對應。
- 允許伺服器主動向客戶端推送資源
Http 與 Https
Http 是超文字傳輸協議,基於 Tcp/Ip 通訊協議來傳遞資料
- 請求資訊明文傳輸,容易被竊聽捕獲
- 資料的完整性未校驗,容易被篡改
- 沒有驗證身份,存在安全性
Https 可以理解為是 Http + ssl 安全套階層協議, 通過 SSL 證書來驗證伺服器的身份,併為瀏覽器和伺服器之間的傳輸資料進行加密(對稱 + 非對稱)
那它們有什麼區別
- 資料是否加密: Http 是明文傳輸,HTTPS是密文
- 預設埠: Http預設埠是80,Https預設埠是443
- 資源消耗:和HTTP通訊相比,Https通訊會消耗更多的CPU和記憶體資源,因為需要加解密處理
- 安全性: http不安全,https相對安全
Https 流程又是怎樣的,就是用 SSL 對資料進行加密解密,然後再利用 Http 傳輸協議進行資料傳輸(密文),具體邏輯是這樣的
當用戶在瀏覽器裡輸入一個https url,然後會預設連線到伺服器的443埠
伺服器必須要有一套數字證書,也就是上邊說的 SSL (安全套階層協議),這套證書其實就是一對公鑰和私鑰(一般需要申請)
伺服器會將自己的數字證書(含有公鑰)返回給客戶端
客戶端收到伺服器端的數字證書之後,會對其進行驗證,如果證書沒問題,則會生成一個金鑰(對稱加密),用證書的公鑰對它加密
客戶端會發起 HTTPS 中的第二個 HTTP 請求,將加密之後的客戶端金鑰傳送給伺服器
伺服器接收到客戶端發來的密文之後,會用自己的私鑰對其進行非對稱解密,解密之後得到客戶端金鑰,然後用客戶端金鑰對返回資料進行對稱加密,這樣資料就變成了密文
伺服器將加密後的密文返回給客戶端
客戶端收到伺服器發返回的密文,用自己的金鑰(客戶端金鑰)對其進行對稱解密,得到伺服器返回的資料
Tcp 三次握手和四次揮手
在聊 Tcp 傳輸協議前,我們先來了解一下 Tcp 報文, 在網上找了一張圖,詳細請檢視
TCP 三次握手和四次揮手需要用到的報文資訊,我在圖裡邊做了備註,這些是需要做個簡單瞭解的,然後再通過兩張圖來了解一下 Tcp 三次握手和四次揮手
三次握手
- 首先三次握手是由客戶端發起的,向服務端發起建立一個 Tcp 連結,此時將標誌位 SYN 位置 1,並攜帶一個請求序列號 seq = x
序列號 x 是 32 位,隨機生成的 (面向客戶端)
- 服務端收到客戶端的建立連結請求,那麼服務端要做出迴應的,所以會將確認標誌位 ACK 置 1 ,並生成確認序列號 ack = x + 1
確認序列號是接收的請求序列號 + 1
, 與此同時, 服務端也要向客戶端發起一個建立連結請求,將標誌位 SYN 位置 1,也攜帶一個請求序列號 seq = y序列號 y 是 32 位,隨機生成的(面向服務端)
- 此時,客戶端已經知道服務端收到請求並同意建立連結了,那麼自己也需要給服務端一個迴應,再次發出請求,也將確認標誌位 ACK 置 1 ,並生成確認序列號 ack = y + 1
ok, 通過以上3步,完成了 TCP 三次握手,為什麼兩次不行 ? 原因很簡單,通過前兩步,客戶端雖然知道可以建立連結了,但是服務端還是一臉懵逼,所以最後一步則是給服務端一個迴應,告訴服務端,我也準備好了,可以建立連結了
四次揮手
瞭解過三次握手的話,那麼四次揮手就比較簡單了,原理基本相同
- 同理,四次揮手也是由客戶端發起的,向服務端發一個斷開連結的請求,此時將標誌位 FIN 位置 1 ,並攜帶一個請求序列號 seq = x
- 服務端收到客戶端斷開連線的請求時,同樣要給一個迴應,所以會將確認標誌位 ACK 置 1,並生成一個確認序列號 ack = x + 1
- 此時,客戶端接到(服務端已經收到自己斷開連結)的請求了,那麼就坐等斷開咯,可是服務端可能還有一些事情在處理,例如:返回資料過程中....,所以當服務端處理完手頭上的事情了,就會發送一個斷開連結的請求到客戶端,也就是將 FIN 位置 1 ,並生成一個斷開連結的序列號 seq = y
- 客戶端收到服務端的斷開連結請求了,襖,你也處理完了,那我們就斷開吧
ok ,通過以上4步,就完成了 TCP 四次揮手,原理也很簡單,就是雙向的一問一答
Tcp 和 Udp 的區別
- TCP 是面向連線的協議,也就是說,在收發資料前,必須和對方建立安全可靠的連線(傳說中的三次握手 ),而UDP 則是無連線的,只需要目標埠號即可傳送資料
- TCP 只支援點對點,而 UDP 則支援一對一,一對多,多對多,多對一都可以
- TCP 傳輸效率相對較低,因為要建立連結和斷開連結,而 UDP 則不需要,所以相對來講速度快一些
- TCP 面向位元組流,UDP面向報文
- TCP 能保證資料正確性,UDP 則可能丟包
前端常見攻防
XSS
csrf
sql 注入
作者:Hisen 來源:掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。