1. 程式人生 > 其它 >前端瀏覽器網路系列進階(本地儲存,快取,網路,協議,安全)

前端瀏覽器網路系列進階(本地儲存,快取,網路,協議,安全)

前言

前端眼裡只有 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引擎,為什麼這麼說,因為瀏覽器在渲染一個網頁時,一般有三步

  1. 瀏覽器通過 HTMLParser 把 HTML 解析成 DOM Tree (俗稱DOM樹)。
  2. 瀏覽器通過 CSSParser 把 CSS 解析成 CSS Rule Tree(俗稱CSSOM樹)。
  3. 瀏覽器將 JavaScript 通過 DOM API 或者 CSSOM API 將 JS 程式碼解析並應用到佈局中,根據 DOM 樹和 CSSOM 樹來構造 Render Tree(Rander 樹)

最終的 Rander 樹就是整個頁面的文件結構抽象表示,然後按要求呈現響應的結果,所以結合這三步來分析,單純的 Css 渲染引擎從字面的意思上來講,並不能完全表達前兩步

  • 渲染引擎
  • Js引擎

渲染引擎:主要負責取得網頁的內容(HTML、XML、影象等等)、以及計算網頁的顯示方式,然後會輸出至瀏覽器,瀏覽器的核心的不同對於網頁的語法解釋會有不同,所以渲染的效果也不相同

JS引擎:主要負責解析和執行javascript程式碼來實現網頁的動態效果

本地儲存

  • cookie
  • sessionStorage
  • localStorage

通過一個表格來對比一下

特性cookielocalStoragesessionStorage
生命週期 一般由伺服器生成,可以設定過期時間 持久儲存 當前會話層儲存,關閉即清除
資料儲存大小 4K 5M 5M
是否跨域 同源 http 請求中攜帶 , 預設不允許跨域 ,跨域需要設定withCredentials = true,伺服器端需要允許 預設不允許跨域,可以使用 postMessage 解決 cros
儲存位置 伺服器端,每次請求會攜帶存放在 header 中 硬碟 記憶體

關於 cookie 部分屬性還需要注意一下安全性

  • value 如果用於儲存使用者登入狀態,應該將該值加密
  • http-only 不能通過 Js 訪問 Cookie,減少 XSS攻擊
  • secure 只能在協議為 HTTPS 的請求中攜帶
  • same-site 規定瀏覽器不能在跨域請求中攜帶 Cookie,減少 CSRF 攻擊

瀏覽器快取

簡單來說,瀏覽器快取其實就是瀏覽器把HTTP獲取的資源儲存在本地的一種行為

快取的優先順序

  1. 先在記憶體中查詢
  2. 如果記憶體中不存在,則在硬碟中查詢
  3. 如果硬碟中也沒有,那麼就進行網路請求
  4. 請求獲取的資源快取到硬碟和記憶體

快取分類

  • 強快取
  • 協商快取

先來捋一捋邏輯

  1. 當客戶端請求某個資源時,會先根據這個資源的 http header 判斷它是否命中強快取,如果命中,則直接從本地獲取快取資源,不會發請求到伺服器
  2. 當沒有命中強快取時,客戶端會發送請求到伺服器,伺服器通過 request header 驗證這個資源是否命中協商快取,如果命中,伺服器將返回 304,告訴客戶端從快取中獲取
  3. 當協商快取也沒命中時,伺服器就會將資源返回客戶端
  • 當 ctrl+f5 強制重新整理網頁時,直接從伺服器載入,跳過強快取和協商快取
  • 當 f5 重新整理網頁時,跳過強快取,但是會檢查協商快取

強快取

  • Expires(是 http1.0 時的規範,值為一個絕對時間的 GMT 格式的時間字串,代表快取資源的過期時間)
  • Cache-Control:max-age(是 http1.1的規範,強快取利用其 max-age 值來判斷快取資源的最大生命週期,它的值單位為秒)

Cache-Control 還有一些常用其它屬性:

  1. no-cache:需要進行協商快取,傳送請求到伺服器確認是否使用快取。
  2. no-store:禁止使用快取,每一次都要重新請求資料。
  3. public:可以被所有的使用者快取,包括終端使用者和CDN等中間代理伺服器。
  4. 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-ControlEtag/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 三次握手和四次揮手

三次握手

  1. 首先三次握手是由客戶端發起的,向服務端發起建立一個 Tcp 連結,此時將標誌位 SYN 位置 1,並攜帶一個請求序列號 seq = x序列號 x 是 32 位,隨機生成的 (面向客戶端)
  2. 服務端收到客戶端的建立連結請求,那麼服務端要做出迴應的,所以會將確認標誌位 ACK 置 1 ,並生成確認序列號 ack = x + 1確認序列號是接收的請求序列號 + 1, 與此同時, 服務端也要向客戶端發起一個建立連結請求,將標誌位 SYN 位置 1,也攜帶一個請求序列號 seq = y序列號 y 是 32 位,隨機生成的(面向服務端)
  3. 此時,客戶端已經知道服務端收到請求並同意建立連結了,那麼自己也需要給服務端一個迴應,再次發出請求,也將確認標誌位 ACK 置 1 ,並生成確認序列號 ack = y + 1

ok, 通過以上3步,完成了 TCP 三次握手,為什麼兩次不行 ? 原因很簡單,通過前兩步,客戶端雖然知道可以建立連結了,但是服務端還是一臉懵逼,所以最後一步則是給服務端一個迴應,告訴服務端,我也準備好了,可以建立連結了

四次揮手

瞭解過三次握手的話,那麼四次揮手就比較簡單了,原理基本相同

  1. 同理,四次揮手也是由客戶端發起的,向服務端發一個斷開連結的請求,此時將標誌位 FIN 位置 1 ,並攜帶一個請求序列號 seq = x
  2. 服務端收到客戶端斷開連線的請求時,同樣要給一個迴應,所以會將確認標誌位 ACK 置 1,並生成一個確認序列號 ack = x + 1
  3. 此時,客戶端接到(服務端已經收到自己斷開連結)的請求了,那麼就坐等斷開咯,可是服務端可能還有一些事情在處理,例如:返回資料過程中....,所以當服務端處理完手頭上的事情了,就會發送一個斷開連結的請求到客戶端,也就是將 FIN 位置 1 ,並生成一個斷開連結的序列號 seq = y
  4. 客戶端收到服務端的斷開連結請求了,襖,你也處理完了,那我們就斷開吧

ok ,通過以上4步,就完成了 TCP 四次揮手,原理也很簡單,就是雙向的一問一答

Tcp 和 Udp 的區別

  • TCP 是面向連線的協議,也就是說,在收發資料前,必須和對方建立安全可靠的連線(傳說中的三次握手 ),而UDP 則是無連線的,只需要目標埠號即可傳送資料
  • TCP 只支援點對點,而 UDP 則支援一對一,一對多,多對多,多對一都可以
  • TCP 傳輸效率相對較低,因為要建立連結和斷開連結,而 UDP 則不需要,所以相對來講速度快一些
  • TCP 面向位元組流,UDP面向報文
  • TCP 能保證資料正確性,UDP 則可能丟包

前端常見攻防

XSS

csrf

sql 注入


作者:Hisen 來源:掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。