六脈神劍之運行脈——從用戶輸入URL到頁面顯示知識梳理

前言

本文目標

  1. 經過從輸入url到頁面顯示這一整個運行過程,梳理如下相關知識點javascript

    • http1.1, http2.0https, TCP/UDP網絡架構緩存
    • 瀏覽器進程&線程渲染機制跨域安全(XSS,CSRF)
  2. 主要是把知識成體系的創建起來css

依賴知識

  1. 線程與進程html

  2. 併發與並行前端

  3. 同步與異步vue

  4. 阻塞與非阻塞java

  5. 瀏覽器的進程和線程node

主體大綱

  1. 用戶輸入 (輸入解析react

  2. 檢查緩存(強緩存和協商緩存nginx

  3. DNS解析(IP反查DNS緩存git

  4. 創建TCP鏈接(三次握手UDP網絡架構等待tcp隊列

  5. 創建TLS鏈接 (HTTPS

  6. 發起http請求(http1.0http1.1http2.0請求行請求頭請求體

  7. 服務器處理請求

  8. 服務器響應請求(響應行響應頭響應體狀態碼

  9. 斷開TCP鏈接(四次分手

  10. 渲染開始(從進程的角度講中間有一個導航流程,)

  11. 構建dom樹

  12. 樣式解析計算(css阻塞問題結構化,屬性標準化,元素樣式具體化(繼承,層疊,特指)

  13. 建立佈局樹(建立可見元素的佈局樹計算節點位置優化(重繪,重排相關)

  14. 分層,生成分層樹(緣由分層條件

  15. 生成繪製列表,交給合成線程

  16. 合成線程將圖層分爲圖塊,光刪化將圖塊變成位圖(分圖塊緣由

  17. 合成線程發送繪製圖塊命令,給瀏覽器進程

  18. 瀏覽器生成頁面,顯示到顯示器上

依賴知識

1. 線程與進程

  1. 進程

    • 它是程序的一次執行過程,就是一個程序的運行實例,程序執行過程當中分配和管理資源的基本單位,
    • 詳細的說,啓動一個程序的時候,操做系統會爲該程序建立一塊內存,用來存放代碼、運行中的數據和一個執行任務的主線程,咱們把這樣的一個運行環境叫進程
  2. 線程

    • 是CPU調度和分派的基本單位,和同一進程的其餘線程共享資源
  3. 關係

    • 線程是進程的一部分,不能單獨存在的,它是由進程來啓動和管理的,一個進程有多個線程

2. 併發和並行

  • 併發的關鍵是你有處理多個任務的能力,不必定要同時。(吃飯吃一半電話來了,去打電話,再吃飯)
  • 並行的關鍵是你有同時處理多個任務的能力(一邊打電話,一邊吃飯,)

關鍵區別是否同時同時就是並行

3. 同步和異步

同步和異步關注的是消息通訊機制

  1. 同步
  • 在發出一個調用時,在沒有獲得結果以前,該調用就不返回
  • 調用者主動等待這個調用的結果
  1. 異步
  • 一個異步過程調用發出後,調用者不會馬上獲得結果
  • 而是在調用發出後,被調用者經過狀態、通知來通知調用者,或經過回調函數處理這個調用

關鍵區別 主動等,仍是被通知

4. 阻塞和非阻塞

阻塞和非阻塞關注的是程序在等待調用結果(消息,返回值)時的狀態.

  1. 阻塞
  • 調用結果返回以前,當前線程會被掛起
  • 調用線程只有在獲得結果以後纔會返回,不能作別的事
  1. 非阻塞
  • 在不能馬上獲得結果以前,該調用不會阻塞當前線程
  • 當前線程能夠作別的事

關鍵區別結果返回前,可不能夠作別的

5. 瀏覽器線程與進程

從輸入url到頁面顯示這一整個運行過程,瀏覽器進程和線程是必不可少的角色,先來了解下他們

瀏覽器線程與進程關係圖以下

瀏覽器線程與進程關係圖

瀏覽器的多進程

  1. 瀏覽器主進程:界面顯示,用戶交互,子進程管理,存儲
  2. 插件進程:每種類型插件對應一個進程
  3. GPU進程: UI的繪製,包括3D圖像
  4. 渲染進程:每一個tab一個進程
  5. 網絡進程: 加載頁面網絡資源

渲染進程的多線程

  1. GUI渲染線程:

    • 負責渲染瀏覽器界面,解析html, css
    • 與JS引擎線程互斥,js引擎執行時,GUI線程會被掛起, 會形成頁面阻塞
  2. JS引擎線程

    • 解析JS腳本,運行代碼
    • 與GUI渲染線程互斥
  3. 事件觸發線程

    • 是屬於瀏覽器,用來控制事件循環,

    • 當js執行如setTImeout,等異步代碼,會將染污添加到事件線程中

    • 對應事件符合條件被觸發時改線程會把事件添加到待處理隊列的隊尾,等待js引擎的處理

    • js是單線程的關係,待處理隊列中的事件都得排隊等待js引擎處理

js引擎線程只負責執行看病,事件觸發線程幫他掛號,排隊

  1. 定時觸發器線程

    • 就是setINterval,setTimeout所在線程

    • 瀏覽器的定時計數器,並非由js引擎計數的,(js引擎單線程,處於阻塞狀態會影響計時的準確性)

    • 經過單獨線程計時,並觸發定時(計時完畢後,添加到事件隊列,等待js引擎空閒後執行)

    • w3c規定,setTimeout 低於4ms 時間間隔的都算爲4ms

定時觸發器線程,幫助計時

  1. 異步http請求線程

    • XMR鏈接後,瀏覽器新開一個線程請求

    • 檢測到狀態變動,設有回調函數,異步線程產生狀態變動事件,就將回調再放入事件隊列中,等待js引擎執行

在瀏覽器中打開一個頁面,會開啓幾個進程

  • 通常狀況是4個
  • 1個瀏覽器進程、1個網絡進程、一個GPU進程,一般一個Tab頁對應一個渲染進程,

但有其它狀況

  1. 若是頁面中有iframe的話,iframe也會運行在單獨的進程中

  2. 若是頁面有插件,插件也須要開啓一個單獨的進程

  3. 若是瀏覽器中裝了擴展,一個擴展對應一個進程

  4. 若是兩個頁面屬於同一站點,而且從a頁面中打開b頁面,那麼他們會公用一個渲染進程

一. 用戶輸入

  1. 用戶輸入URL,瀏覽器進程會根據URL規則進行斷定解析,
  • 若是是搜索詞,則使用瀏覽器設置的默認搜索引擎,
  • 若是是URL,則會根據規則把URL補全,好比輸入baidu.com 則補充協議 https://www.baidu.com/
  1. 瀏覽器進程會經過進程間通訊(IPC)把 URL 請求發送至網絡進程網絡進程接收到 URL 請求後,發起URL請求流程, 構建請求行信息,

二. 檢查緩存

  • 網絡進程會查找本地緩存是否緩存了該資源。若是有緩存資源且緩存有效,那麼直接返回資源給瀏覽器進程;若是在緩存中沒有查找到資源,那麼直接進入網絡請求流程

那麼若是纔會有緩存且斷定緩存有效呢

強緩存和協商緩存

緩存分爲強緩存和協商緩存

1. 強緩存

  1. Expries
    • http1.0 服務端返回的數據到期時間
    • 缺點:客戶端和服務器端時間有偏差
  2. cache-control
    • http1.1 多個屬性
    • private:客戶端能夠緩存
    • public:客戶端和代理服務器均可以緩存
    • max-age=t:緩存內容將在t秒後失效
    • no-cache:須要使用協商緩存來驗證緩存數據
    • no-store:全部內容都不會緩存

2. 協商緩存

  1. Last-Modified
    • http1.0 資源最後修改時間(服務器在響應請求時,會告訴瀏覽器資源的最後修改時間)

    • 缺點:

      【1】資源被修改,時間變了,但實際內容沒變

      【2】短期頻繁修改,秒如下級別沒法捕捉

    • if-Modified-Since: 再次請求時會利用此屬性攜帶Last-Modified時間,用於服務資源比較

    • if-Unmodified-Since: 從某個時間點算起, 是否文件沒有被修改,使用的是相對時間,不須要關心客戶端和服務端的時間誤差,利用它實現斷點續傳功能的判斷

  2. Etag
    • http1.1 服務器生成的惟一標識
    • If-None-Match 再次請求時會利用此屬性攜帶緩Etag標識,用於服務資源比較
    • If-Match 資源比較匹配了纔會返回內容,不匹配則416(請求沒法知足)

3. 優先級

優先級 強緩存 > 協商緩存 高版本 > 低版本

三. DNS解析

  • 進入網絡請求流程,首先要進行DNS解析,也就是IP反查,獲取IP地址,

域名緩存

  • DNS也是有緩存的,優先級由高到低
    1. 瀏覽器緩存
    2. 系統緩存
    3. 路由緩存
    4. host
    5. 域名服務器

四. 創建TCP鏈接

  • 拿到服務器 IP 地址,和服務器創建TCP連接,

網絡架構 四層?五層?七層?

OSI七層 網絡五層 TCP/IP四層
應用層 應用層 應用層
表示層
會話層
傳輸層 傳輸層 傳輸層
網絡層 網絡層 網絡層
數據鏈路層 數據鏈路層 數據鏈路層
物理層 物理層 -
  1. 應用層 HTTP 生成http請求報文 數據包發送

  2. 傳輸層 TCP/UDP 報文分割,打上標記及端口號 數據包送達具體應用

    • 【UDP】協議傳輸速度快,可是不提供重發機制,不保證數據可靠性, 適用於關注速度,不嚴格要求數據的領域,視頻,互動遊戲等
    • 【TCP】協議 傳輸速度慢,提供從新傳輸機制,提供數據包重排機制,保證數據可靠性
  3. 網絡層 IP 增長做爲通訊目的地的mac地址 數據包送達主機

三次握手

  • SYN是同步,ACK是應答
  • seq是同步序列號,ack是應答號,
  • 兩端會使用 ISN產生器,產生各自的 初始序列號 (Initial Sequence Number, ISN), 一般二者並不相等
  1. 第一次握手:客戶端給服務端發一個 SYN 報文,並指明客戶端的初始化序列號 ISN(c)。此時客戶端處於 SYN_SEND 狀態。
  2. 第二次握手:服務器收到客戶端的 SYN 報文以後,會以本身的 SYN 報文做爲應答,而且也是指定了本身的初始化序列號 ISN(s),同時會把客戶端的 ISN + 1 做爲 ACK 的值,表示本身已經收到了客戶端的 SYN,此時服務器處於 SYN_REVD 的狀態。
  3. 第三次握手:客戶端收到 SYN 報文以後,會發送一個 ACK 報文,固然,也是同樣把服務器的 ISN + 1 做爲 ACK 的值,表示已經收到了服務端的 SYN 報文,此時客戶端處於 establised 狀態。
  4. 服務器收到 ACK 報文以後,也處於 establised 狀態,此時,雙方以創建起了連接。
'Client'                                     'Server'1】SYN(seq=ISN(c))
`SYN_SEND`      --------------------->
同步已發送  
                【2】SYN + ACK(seq=ISN(s),ack=ISN(c)+1`establised`    <---------------------     `SYN_REVD`
 已鏈接                                     同步接收
                【3】ACK(ack=ISN(s)+1)
                --------------------->     `establised` 
                                            已鏈接
複製代碼

爲何三次

  • 須要三次握手雙方纔能確認本身和對方的接收與發送能力是否正常

TCP和UDP

  1. UDP協議
    • 傳輸速度快,可是不提供重發機制,不保證數據可靠性,
    • 適用於關注速度,不嚴格要求數據的領域,視頻,互動遊戲等
  2. TCP協議
    • 傳輸速度慢,提供從新傳輸機制,提供數據包重排機制,保證數據可靠性

TCP隊列等待

  • 同一個域名同時最多隻能創建 6 個 TCP 鏈接,多餘6個請求同時發生,那麼剩下的請求會進入排隊等待狀態
  • http1.1一個tcp同時只能處理一個請求,瀏覽器會爲每一個域名維護6個tcp鏈接,可是每一個tcp鏈接是能夠複用的,也就是處理完一個請求以後,不斷開這個tcp鏈接,能夠用來處理下個http請求
  • http2是能夠並行請求資源的,瀏覽器只會爲每一個域名維護一個tcp鏈接

五. 創建TLS鏈接

  • 若是是HTTPS請求還要創建TLS連接

    HTTPS連接和HTTP連接都創建在TCP協議之上

    HTTP請求 = TCP握手

    HTTPS請求 = TCP握手 + TLS握手

https

  • https簡單說就是對數據傳輸加密,保證安全

  • HTTP + 加密 + 認證 + 完整性保護 = HTTPS

  • HTTP 協議與 TCP/IP 協議中間 加了一層HTTPS協議,HTTP -> TLS -> TCP -> IP

http存在問題

  1. 被竊聽:使用了明文
  2. 遇假裝:不驗證通訊方身份
  3. 遭篡改:沒法證實報文完整性

加密方式

  1. 對稱密鑰加密(共享密鑰加密):加密解密用同一個密鑰
  • 密鑰必須發給對方,過程當中可能被竊聽
  1. 非對稱密鑰加密(公開密鑰加密):一把私有密鑰(只有本身知道),一把公開密鑰(任何人均可以知道)
  • 發送方用公開密鑰加密,接收方用私有密鑰解密
  • 處理速度較慢

HTTPS採用共享密鑰加密公開密鑰加密混合加密機制,保證處理速度和安全性

  • 交換密鑰階段: 使用公開密鑰加密 能夠簡單理解爲加密的是共享密鑰的公鑰(保證安全)
  • 創建通訊交換報文: 使用共享密鑰加密 加密的是通訊的報文(保證速度)

認證方式

  1. 數據傳輸被中間人竊聽
    • 就要加密傳輸,因此使用對稱加密,加密解密相同密鑰
  2. 數據沒法被竊聽了,可是雙方爲了約定對稱加密算法和密鑰,這些數據也要傳輸,
    • 因此使用非對稱加密方式加密對稱加密的密鑰,公鑰傳給客戶端用來加密,私鑰服務端本身留着解密
  3. 這樣雖然中間人不能解密獲得真正的數據,可是非對稱加密的公鑰可能會被篡改,
    • 爲了驗證公鑰的真實性,因此使用第三方認證機構
    • 機構選擇一種單向Hash算法(好比MD5)對公鑰進行加密,生成摘要,單向Hash算法有一種特色就是單向不可逆的,這就防止了信息被篡改
    • 機構會利用本身的私鑰把摘要加密就生成了數字簽名,數字簽名和原有的公鑰信息和在一塊兒成爲數字證書,把證書給客戶端
    • 客戶端會拿事先放好的機構公鑰對數字簽名解密生成摘要,再利用hash算法服務器傳來公鑰生成摘要進行比對認證,
  4. 使用服務器的公開密鑰加密報文發送
  5. 服務器用私有密鑰解密報文

SSL和TLS

  • SSL 是一種安全傳輸協議,TLS 是SSL v3.0的升級版,目前全部的HTTPS都是用的是TLS

握手過程

借用【HTTP圖解】中的過程(描述簡化)

  1. 【Client Hello】客戶端發送支持的SSL的指定版本加密組件列表(所使用的加密算法及密匙長度等)。
  2. 【Server Hello】服務器發送 支持的SSL版本以及加密組件
  3. 服務器發送 證書(數字簽名+公鑰)
  4. 【Server Hello Done】服務器發送【握手協商部分結束】
  5. 【Client Key Exchange】客戶端迴應,發送Pre-master secret(PMS)的隨機密碼串(已用公匙加密,認證過程也包含在內)
  6. 【Change Cipher Spec】客戶端告訴服務端,我之後就用這個密鑰(PMS)加密啦
  7. 【Finished】客戶端發送報文,包含鏈接至今所有報文的總體校驗值。此次握手協商是否可以成功,要以服務器是否可以正確解密該報文做爲斷定標準。
  8. 【Change Cipher Spec】服務器發送報文
  9. 【Finished】服務器發送報文
  10. 服務器和客戶端的Finished報文交換完畢,SSL連創建完成,能夠發送HTTP請求,受到SSL保護
  11. 應用層協議通訊,即發送HTTP響應。
  12. 最後由客戶端斷開鏈接。斷開鏈接時,發送close_notify報文。

六. 發起http請求(http1.1http2.0

  • 構建請求行、請求頭等信息, Cookie 等數據加到請求頭中,向服務器發送請求信息

請求信息

  1. 請求行
    • 請求方法
    • 請求URI
    • http協議版本
  2. 請求頭
  3. 請求體

http1.1

  1. 複用連接

    • 經過Keep-Alive持久化連接,只要瀏覽器或者服務器沒有明確斷開鏈接,那麼該TCP鏈接會一直保持,因此處理完一個請求以後,能夠用來處理下個http請求
  2. 管線化

    • 便可以同時並行發送多個請求, 不須要等待響應再發送下一個請求,
    • 可是服務器依然須要根據請求順序來回復瀏覽器的請求,
    • 並無完美的解決隊頭堵塞(某個請求由於某些緣由沒有及時返回,那麼就會阻塞後面的全部請求)問題
  3. 緩存處理

    • 新增了緩存控制策略Entity tagIf-Unmodified-Since, If-Match, If-None-Match(此處可看緩存
  4. 帶寬優化及網絡鏈接的使用

    • HTTP1.0中,存在浪費帶寬的現象,例如客戶端只是須要某個對象的一部分,而服務器卻將整個對象送過來了,而且不支持斷點續傳功能,
    • HTTP1.1則在請求頭引入了range頭域,它容許只請求資源的某個部分,即返回碼是206(Partial Content),這樣就方便了開發者自由的選擇以便於充分利用帶寬和鏈接。
  5. 錯誤通知的管理

    • 在HTTP1.1中新增了24個錯誤狀態響應碼,例如:409(Conflict)表示請求的資源與資源的當前狀態發生衝突;410(Gone)表示服務器上的某個資源被永久性的刪除
  6. Host頭處理

    • 在HTTP1.0中認爲每臺服務器都綁定一個惟一的IP地址,所以請求消息沒有傳遞主機名
    • 後來,一臺物理服務器上能夠存在多個虛擬主機(Multi-homed Web Servers),而且它們共享一個IP地址。
    • HTTP1.1的請求消息和響應消息都應支持Host頭域,且請求消息中若是沒有報錯400

SPDY

  • 對HTTP1.優化
  • HTTP -> SPDY -> SSL -> TCP -> ...
  1. 下降延遲,針對HTTP高延遲的問題,SPDY優雅的採起了多路複用(multiplexing)。多路複用經過多個請求stream共享一個tcp鏈接的方式,解決了HOL blocking的問題,下降了延遲同時提升了帶寬的利用率。

  2. 請求優先級

    • 能夠給每一個請求設置優先級,這樣重要的請求就會優先獲得響應。
    • 好比瀏覽器加載首頁,首頁的html內容應該優先展現,以後纔是各類靜態資源文件,腳本文件等加載,這樣能夠保證用戶能第一時間看到網頁內容。
  3. header壓縮

    • SPDY 使用通用的DEFLATE 算法
  4. HTTPS加密

    • 提升傳輸數據的安全性
  5. 服務端推送

    • 服務器能夠對客戶端的一個請求發送多個響應

http2.0

  • 改善用戶使用web速度體驗,對HTTP1.優化 基於 SPDY 設計
  1. 二進制格式

    • HTTP1.x 採用文本格式
    • HTTP2.0 採用二進制格式,方便且健壯
  2. 多路複用

    • http2.0雖然依然遵循請求-響應模式,但客戶端發送多個請求和服務端給出多個響應的順序不受限制,這樣既避免了"隊頭堵塞",又能更快獲取響應。
    • 例如:在複用同一個TCP鏈接時,服務器同時(或前後)收到了A、B兩個請求,先回應A請求,但因爲處理過程很是耗時,因而就發送A請求已經處理好的部分, 接着迴應B請求,完成後,再發送A請求剩下的部分
    • 某個請求任務耗時嚴重,不會影響到其它鏈接的正常執行。
  3. header壓縮

    • 專門爲首部壓縮而設計的 HPACK 算法
  4. 服務端推送

    • 基於SPDY

七. 服務器處理請求 (跨域XSSCSRF

  • 發起請求非同源會報跨域問題,通常是CORS解決
  • 中間可能會通過調度服務器nginx控制負載均衡
  • 服務器接收到請求信息後,會根據請求信息生成響應數據

跨域

基本介紹

  • 跨域是指一個域下的文檔或腳本試圖去請求另外一個域下的資源

跨域是因爲瀏覽器的同源策略

同源策略 出於對瀏覽器安全考慮,防止收到XSS,CSRF攻擊,協議+域名+端口有一個不一樣,則是非同源

同源限制策略

  1. cookie, localstroge, indexDB沒法讀取
  2. dom和js對象沒法獲取
  3. ajax請求不能發送

9種方法

  1. jsonp
  2. document.domain + iframe
  3. location.hash + iframe
  4. window.name + iframe
  5. postMessage
  6. CORS
  7. nginx代理
  8. nodejs中間件代理
  9. websocket

1.jsonp

  1. 定義:
  • jsonp跨域數據交互協議
  1. 原理:
  • Web頁面上調用js文件時則不受跨域的影響,好比靜態資源的加載(不只如此,咱們還發現凡是擁有src這個屬性的標籤都擁有跨域的能力,好比<script>、<img>、<iframe>
  1. 應用:
  • 爲了遠端js知道須要調用的函數,且可能會調用不少數據對象,對應不一樣的函數

  • js腳本就不能寫死,咱們動態生成js腳本,利用傳參的不一樣,來區分調用

  1. 缺點:
  • 只能實現get一種請求。

2.CORS

跨域資源共享(Cross-origin resource sharing)

對那些可能對服務器數據產生反作用的 HTTP 請求方法 瀏覽器必須首先使用 OPTIONS 方法發起一個預檢請求(preflight request), 從而獲知服務端是否容許該跨域請求 服務器確認容許以後,才發起實際的 HTTP 請求

不會觸發CORS預檢的請求稱爲簡單請求

  • 簡單請求
  1. GET,POST,HEAD

  2. 不得人爲設置其餘首部字段

  3. content-type 僅限( text/plain multipart/form-data application/x-www-form-urlencoded

  • 複雜請求(會觸發預檢請求)

普通跨域請求:服務端設置 Access-control-allow-origin

攜帶cookie跨域請求:

  • 前端後端都需設置
  • 前端:withcredentials
  • 後端:Access-Control-Allow-Credentials: true
  • 服務器不得設置 Access-Control-Allow-Origin 的值爲*, 必須是某個具體的域名

3.nginx 代理跨域

  1. nginx 解決iconfont跨域
  • 瀏覽器跨域訪問js、css、img等常規靜態資源被同源策略許可,
  • 但iconfont字體文件(eot|otf|ttf|woff|svg)例外,
  • 此時可在nginx的靜態資源服務器中加入如下配置
location / {
  add_header Access-Control-Allow-Origin *;
}
複製代碼
  1. nginx 反向代理接口跨域

原理:

同源策略是瀏覽器的安全策略,不是http協議的一部分,服務器端調用接口, 不會執行js腳本,不須要同源策略,也就不存在跨域問題

實現:

  • 經過nginx配置代理服務器(與a同域名,不一樣端口)作跳板機
  • 反向代理訪問b接口,並修改cookie 中domain 信息,方便當前域cookie寫入,實現跨域登陸

nginx配置

server{
    listen 81;
    server_name www.a.com;
    locaton / {
        proxy_pass https://b.com
        add_header Access-Control-Allow-Origin http://a.com; #當前端只跨域不帶cookie時,可爲*
        add_header Access-Control-Allow-Credentials true;
    }
}
複製代碼

4.nodejs中間件代理跨域

原理:

  • 大體與nginx相同,經過啓動一個代理服務器,實現數據的轉發
  • 且可經過cookieDomainRewrite 修改響應頭中cookie 中域名,實現當前域cookie寫入

5.webSocket協議跨域

websocket是H5新協議,實現瀏覽器與服務器全雙工通訊,同時容許跨域,

使用socket.io(websocket原生封裝)

6.postMessage

postMessage是h5 XHR的API,是跨域操做的window屬性之一 解決

  1. 頁面與新開窗口的數據傳遞
  2. 多窗口之間的消息傳遞
  3. 頁面與iframe消息傳遞
  4. 以上三種場景的跨域傳遞

應用 postMessage(data, origin) data: 須要傳遞的數據 JSON.String() 部分瀏覽器只支持字符串 origin: 協議+ 域名 + 端口 能夠 * 傳遞任意窗口

iframe.contentWindow.postMessage

7. document.domain + iframe

僅限子域不一樣跨域 兩個頁面強制設置 document.domain 爲基礎主域,就實現了同域

8.location.hash + iframe

a與b不一樣域,b是a的iframe ,a能傳給b ,但b沒法傳a,

利用c,c與a是同域,且c是b的iframe,b 傳給c, c再傳給a

實現了a與b跨域雙向通訊,

原理: a與b跨域通訊,經過c來實現,不一樣域之間利用iframe的location.hash傳值, c與a同域,因此c可經過parent.parent訪問a頁面全部對象。

實現: a -> b -> c -> a

9.window.name + iframe

原理:window.name 屬性 再不一樣頁面,甚至不一樣域名,加載以後依然存在,並支持 較大存儲(2MB)

a,b跨域, b是a的iframe, 實現:

  • 第一次,加載跨域頁,並留存數據於window.name
  • 成功後,改變 改變b的location爲a的同域,使iframe.onload再次執行,
  • 第二次,讀取同域的window.name

小結

  1. CORS支持全部類型的HTTP請求,是跨域HTTP請求的根本解決方法。
  2. JSONP只支持GET請求,JSONP的優點在於支持老式瀏覽器,以及能夠向不支持CORS的網站請求數據
  3. 無論是Node中間件代理仍是nginx反向代理,主要是經過同源策略對服務器不加限制
  4. 平常工做中,用的比較多的跨域方案仍是cors和nginx反向代理

XSS(跨站腳本攻擊)

  • 經過在 有安全漏洞的web網站註冊用戶的瀏覽器上 運行非法的HTML標籤或Javascript進行的一種攻擊

  • 本質是:惡意代碼未通過濾,瀏覽器沒法分辨,致使惡意代碼被執行

影響

  1. 騙取用戶我的信息
  2. 幫助攻擊者發送惡意請求
  3. 顯示僞造的文章

分類

  1. 存儲型 XSS 惡意代碼存在數據庫,由服務端取出,插入在html執行
  2. 反射型 XSS 惡意代碼存在URL,由服務端取出,插入在html執行
  3. DOM型 XSS 惡意代碼存在數據庫/客戶端/URL前端JavaScript取出, 插入在JavaScript執行

DOM型 XSS屬於前端安全漏洞,其餘兩種屬於後端安全漏洞

預防

預防存儲型和反射型 XSS 攻擊

  1. 前端渲染,把代碼和數據分隔

明確渲染內容的類別,幫助瀏覽器分辨是文本(.innerText),屬性(.setAttribute)或是樣式(.style),用對應的方法去渲染

適用於內部管理項目

  1. 轉義 HTML

對 HTML 作充分轉義

適用於要求性能,SEO的對外項目

預防 dom型 XSS 攻擊

  1. 當心使用 .innerHtml,.outerHtml,document.write(), 不要把不可信數據插入html 儘可能使用.textCotent,.setAttribute()

  2. 若是用vue/react框架,當心使用v-html/dangerouslySetInnerHTML, 也可減小XSS隱患

  3. 如下都能把字符串做爲代碼運行,當心使用:

    • dom內聯事件監聽器location,onclick,onload,onmouseover
    • <a>標籤的屬性
    • javascript的eval(),setTimeout,setInterval()

其餘 預防 XSS 攻擊

  1. Content Security Policy (CSP)內容安全策略

    • 禁止加載外域代碼,防止複雜的攻擊邏輯
    • 禁止外域提交,被攻擊數據不會泄漏到外域
    • 禁止內聯腳本執行,
    • 禁止未受權腳本執行
  2. 內容長度控制,防止複雜攻擊

  3. 驗證碼,防止腳本提交

  4. HTTP-only Cookie, 禁止js讀取cookie

小結

  1. XSS預防 主要靠轉義 且要保證
  • 正確性 要防止多餘和錯誤的轉義,避免正常的用戶輸入出現亂碼
  • 完整性 須要在所有須要轉義的位置,對數據進行對應的轉義
  • 針對性 針對不一樣的上下文調用不一樣的轉義規則

CSRF(跨站請求僞造)

介紹

誘導受害者進入第三方網站,向被攻擊網站發起請求,利用受害者在被攻擊網站獲取的註冊憑證(cookie),繞事後臺驗證,以此冒充用戶對被攻擊網站執行某項操做。

本質:冒充用戶,發起請求,執行惡意操做(憑證也不能證實請求是用戶主動想要發起的)

特色

  1. 攻擊通常發起在第三方網站,被攻擊網站沒法防範
  2. 攻擊利用登陸憑證,冒充用戶,而不是直接盜取數據
  3. 攻擊者並不能獲取憑證,只是使用
  4. 攻擊利用,URL,href,Form,等難以追蹤

分類

  1. GET類型 訪問第三方網站,惡意請求放在靜態資源上,頁面加載是就會自動發送http請求 例如<img href="http...">
  2. POST類型 一般使用的是一個自動提交的表單,模擬用戶完成POST操做,例如<form action="http..."></form>
  3. 連接類型 誘導用戶主動點擊連接觸發,例如<a href="http...">

預防

針對CSRF特色

  1. 一般發生在第三方
  2. 攻擊者不能獲取到cookie 只是使用

做出專門預防

  1. 阻止不明外域訪問
    • 同源檢測
    • Samesite Cookie
  2. 提交時要求附加本域纔可獲取的信息
    • token(CSRF攻擊時不會自動帶上token)
    • 雙cookie驗證

同源檢測

  1. 判斷請求是否來自外域,利用請求的header屬性originreferer

  2. 缺點:

    • 攻擊者能夠隱藏Referer referrerpolicy="no-referrer
    • IE低版本瀏覽器有問題
    • HTTPS跳轉HTTP Referer丟失
    • flash跳轉其餘網站,Referer雜亂
  3. 阻止外域請求時,須要過濾掉正常的外戰請求(例如百度搜索,友好連接)

Token

用戶登陸時,服務端返回 token,以後的請求都攜帶token,用以辨別正常請求和攻擊請求

缺點:

  1. CSRF攻擊時只是不會自動帶上token, 若是存在XSS漏洞,攻擊者仍是能夠寫腳本(XSS)獲取token,進而進行CSRF攻擊
  2. 在會話中存儲CSRF Token比較麻煩,並且不能在通用的攔截上統一處理全部的接口

雙重Cookie

與token原理大體相同,

用戶訪問網站時,服務端向請求域注入一個cookie,隨機字符,以後的請求都攜帶cookie,用以辨別正常請求和攻擊請求

優勢:

  1. 無需session存儲,可統一攔截檢驗

缺點:

  1. 若是存在XSS漏洞,仍是可獲取cookie, 進而進行CSRF攻擊
  2. 子域名沒法隔離
    • 先後端是不一樣子域,沒法共享cookie,網站沒法獲取後端注入的cookie
    • 若是cookie 注入在主域,那麼其餘子域也可修改此cookie

沒法大規模應用

samesite cookie 屬性

根源解決問題,改進http協議,set-cookie響應頭添加samesite屬性

  1. Samesite=Strict 嚴格模式:非本域請求不會攜帶此cookie

  2. Samesite=Lax 寬鬆模式:第三方請求,且同時是GET請求,能夠攜帶

缺點:

  1. 設置爲Strict時,子域名或者是新標籤從新打開剛登錄的網站,cookie不會攜帶,體驗差
  2. 不支持子域,每一個子域名都須要用戶從新登陸一次

不成熟,有待發展

小結

  • 目前業界針對CSRF的防護,一致的作法是使用Token
  • 咱們也能夠經過安全測試行爲監控上傳文件&內容校驗,提高網站安全性

八. 瀏覽器響應請求(響應信息, 狀態碼

  • 收到服務器返回的響應數據,網絡進程開始解析響應頭
  • 若是發現返回的狀態碼是 301 或者 302,重定向到其餘 URL,就從新發起HTTP請求

響應信息

  1. 響應行
    • http協議版本
    • 狀態碼
  2. 響應頭
  3. 響應體

狀態碼

  1. 2XX 成功

    • 200 OK,表示從客戶端發來的請求在服務器端被正確處理
    • 201 Created 請求已經被實現,並且有一個新的資源已經依據請求的須要而創建
    • 202 Accepted 請求已接受,可是還沒執行,不保證完成請求
    • 204 No content,表示請求成功,但響應報文不含實體的主體部分
    • 206 Partial Content,進行範圍請求
  2. 3XX 重定向

    • 301 moved permanently,永久性重定向,表示資源已被分配了新的 URL
    • 302 found,臨時性重定向,表示資源臨時被分配了新的 URL
    • 303 see other,表示資源存在着另外一個 URL,應使用 GET 方法丁香獲取資源
    • 304 not modified,表示服務器容許訪問資源,但因發生請求未知足條件的狀況
    • 307 temporary redirect,臨時重定向,和302含義相同
  3. 4XX 客戶端錯誤

    • 400 bad request,請求報文存在語法錯誤
    • 401 unauthorized,表示發送的請求須要有經過 HTTP 認證的認證信息
    • 403 forbidden,表示對請求資源的訪問被服務器拒絕
    • 404 not found,表示在服務器上沒有找到請求的資源
    • 408 Request timeout, 客戶端請求超時
    • 409 Confict, 請求的資源可能引發衝突
  4. 5XX 服務器錯誤

    • 500 internal sever error,服務器端執行時發生錯誤
    • 501 Not Implemented 請求超出服務器能力範圍,例如服務器不支持當前請求所須要的某個功能,或者請求是服務器不支持的某個方法
    • 503 service unavailable,超負載或停機維護,沒法處理請求
    • 505 http version not supported 服務器不支持,或者拒絕支持在請求中使用的 HTTP 版本

九. 斷開TCP鏈接(四次揮手

  • 數據傳輸全都完畢後,斷開TCP連接

四次揮手

通訊的雙方均可釋放鏈接,雙方都處於 establised 狀態,假如是客戶端先發起關閉請求

  1. 第一次揮手:客戶端發送一個 FIN 報文,指定序列號 此時客戶端處於FIN_WAIT1狀態。
  2. 第二次握手:服務端收到後,會發送 ACK 報文,且把客戶端的序列號值 + 1 做爲 ACK 報文的序列號值,代表已經收到客戶端的報文了,此時服務端處於 CLOSE_WAIT狀態。
  3. 第三次揮手:若是服務端也想斷開鏈接了,和客戶端的第一次揮手同樣,發給 FIN 報文,且指定一個序列號。此時服務端處於 LAST_ACK 的狀態。
  4. 第四次揮手:客戶端收到 FIN 以後,同樣發送一個 ACK 報文做爲應答,且把服務端的序列號值 + 1 做爲本身 ACK 報文的序列號值,此時客戶端處於 TIME_WAIT 狀態。等待計時器設置的兩倍的最長報文段(MSL)時間,以確保服務端收到本身的 ACK 報文以後纔會進入 CLOSED 狀態
  5. 服務端收到 ACK 報文以後,就處於關閉鏈接了,處於 CLOSED 狀態
'Client'                                     'Server'1】FIN seq=u
`FIN_WAIT1`      ---------------------> 
  
                【2】ACK,ack=u+1,seq=v
`FIN_WAIT2`      <---------------------     `CLOSE_WAIT`3】FIN,ACK,seq=w,ack=u+1
`TIME_WAIT`      <---------------------     `LAST_ACK`4】ACK ack=w+1, seq=u+1
`2MSL close`     --------------------->     `close` 
                                            
複製代碼

注意

  1. 第二次揮手完成後,TCP鏈接處於半關閉狀態(客戶端再也不向服務器發送數據),服務器若發送數據,客戶端仍然接受。

  2. 爲何鏈接的時候是三次握手,關閉的時候倒是四次握手

    • Server端收到FIN報文時,可能數據尚未傳輸完成,而不會當即關閉連接,
    • 因此先回復一個ACK,傳輸完成在發起FIN,故須要四步握手
  3. 等待2MSL (最長報文壽命)

    • 爲了保證客戶端發送的最後一個ACK報文段可以到達服務器
    • 防止「已失效的鏈接請求報文段」,出如今本鏈接中。

    要確保服務器收到了ACK 報文,沒有收到的話,會從新發 FIN ,客戶端再次收到 FIN 報文以後,就知道以前的 ACK 報文丟失了,而後再次發送 ACK 報文。

十. 渲染準備

  • 瀏覽器爲頁面分配一個渲染進程
  • 瀏覽器進程網絡進程接收到的 HTML 數據提交給渲染進程
  • 接下來進入渲染階段

多頁面公用一個渲染進程 ?

  • 若是從一個頁面打開了另外一個新頁面,而新頁面和當前頁面屬於同一站點的話,那麼新頁面會複用父頁面的渲染進程

十一. 構建dom樹

  • HTML 轉換爲瀏覽器可以理解的結構DOM樹

十二. 樣式解析計算(css阻塞問題結構化屬性標準化元素樣式具體化(繼承,層疊,特指)))

  • 一樣的,把 CSS 轉換爲瀏覽器可以理解的結構

具體解析

  1. 把 CSS 轉換爲瀏覽器可以理解的結構
  2. 轉換樣式表中的屬性值,使其標準化
  3. 計算出 DOM 樹中每一個節點的具體樣式
    • 繼承層疊特指,優先級由低到高

    • 繼承,某些父節點樣式是能夠繼承給子節點的,例如,文本屬性,colorfont-size 例如字體顏色

    • 層疊,定義瞭如何合併來自多個源的屬性值的算法,多個來源,優先級由低到高

      • 瀏覽器默認樣式表
      • 用戶樣式表(用戶強制放大)
      • 連接樣式表
      • 嵌入樣式
      • 行內樣式
    • 特指, 選擇器優先級,由高到低,I-C-E, ID,class,element

css 阻塞問題

  • css加載不會阻塞DOM樹解析,但會阻塞佈局樹的構建
  • css下載是異步的,但構建佈局樹是須要dom和css同時存在的

十三. 建立佈局樹(建立可見元素的佈局樹計算節點位置優化(重繪,重排)

  • 建立佈局樹, 計算出 DOM 樹中可見元素的幾何位置

重繪和重排

  • js動態修改了DOMCSS,就會致使重繪和重排
  • 重繪:屬性或樣式發生改變,不影響佈局,繪製及以後的階段都會從新進行
  • 重排:佈局或者幾何屬性須要改變, 佈局以及以後的階段都會從新進行

優化 減小重排和重繪

  1. 瀏覽器:

    • 瀏覽器大多經過隊列機制更新佈局,瀏覽器把修改操做放在隊列中,必定時間後執行後纔會清空隊列,

    • 但若是獲取佈局信息,避免隊列中有影響這些屬性或方法返回值的操做,瀏覽器會直接強制清空隊列,觸發重排與重繪保證正確的返回值

    • 即避免使用獲取佈局信息的方法或屬性,他們會強制渲染刷新隊列

  2. CSS

    • transform 代替 top, 二者本無太大區別,但前者能夠開啓GPU加速
    • 動畫效果應用絕對或固定定位,控制動畫速度可以使用requestAnimationFrame
    • CSS3GPU加速

requestAnimationFrame requestAnimationFrame採用系統時間間隔, 保持最佳繪製效率,不會由於間隔時間太短,形成過分繪製,增長開銷; 也不會由於間隔時間太長,使用動畫卡頓不流暢,讓各類網頁動畫效果可以有一個統一的刷新機制,從而節省系統資源,提升系統性能,改善視覺效果

  1. JS :
    • 避免操做樣式和dom
    • 避免讀取重排&重繪屬性
    • 動畫絕對定位

十四. 分層

  • 分層,生成圖層樹

分層

  • 頁面會有一些複雜效果,爲了不重繪和重排,提升渲染效率,會生成單獨專用的圖層
  • 正常節點都在同一個默認圖層裏

生成單獨圖層的條件

  1. 擁有具備3D變換的CSS屬性

  2. 視頻解碼的<video>節點

  3. <canvas>節點

  4. CSS3動畫

  5. CSS加速屬性的元素(will-change)

注意:建立一個單獨圖層的時,佔用的內存也會大大增長

十五. 繪製

  • 爲圖層樹中每一個圖層生成繪製列表,交給合成線程

十六. 分塊,光柵化

  • 合成線程會將較大、較長的圖層(當前屏幕沒法徹底顯示)劃分爲圖塊
  • 柵格化將圖塊變成位圖, 柵格化過程會使用 GPU來加速生成

分塊緣由

  • 有的圖層能夠很大,可是經過視口,用戶只能看到頁面的一部分,
  • 若是繪製出全部圖層內容的話,開銷很大,且無必要

位圖

  • 電腦繪製一張圖片,首先是把這個圖片表示爲一種計算機能理解的數據結構, 即二維數組
  • 數組的每一個元素記錄這個圖片中的每個像素的具體顏色
  • 繪製的過程也就是往數組中具體的下標裏填寫像素

十七. 顯示

  • 合成線程發送繪製圖塊命令,給瀏覽器進程
  • 瀏覽器生成頁面,顯示到顯示器上

總結

總的來講兩個部分:請求資源頁面渲染 請求資源

  1. 用戶輸入URL, 瀏覽器解析斷定爲URL,根據規則進行補全
  2. 查找本地有緩存且未過時,則使用本地,不然請求資源
  3. 進行DNS解析 反查域名,還會有DNS緩存
  4. 若是是HTTPS請求還要先創建TLS連接
  5. 創建TCP連接, 三次握手
  6. 發起HTTP請求
  7. 服務器處理,瀏覽器響應
  8. 數據請求完成,斷開TCP連接,四次分手

頁面渲染

  1. 解析HTML, 構建DOM
  2. 解析CSS,構建styleSheets
  3. 建立佈局樹,計算元素的位置
  4. 對佈局分層,生成圖層樹
  5. 生成繪製列表給合成線程
  6. 合成線程把圖層分紅圖塊,並將圖塊轉成位圖
  7. 瀏覽器進程繪製顯示

參考

  1. 瀏覽器工做原理與實踐

  2. 從輸入URL到頁面加載的過程?如何由一道題完善本身的前端知識體系!

  3. 瀏覽器渲染詳細過程:重繪、重排和 composite 只是冰山一角

  4. http圖解

  5. 關於三次握手與四次揮手面試官想考咱們什麼?--- 不看後悔系列

  6. 「真香警告」重學 TCP/IP 協議 與三次握手

  7. TCP鏈接與創建

  8. 注意!是TCP不是HTTP的3次握手與4次揮手

  9. 【建議收藏】2020年中高級Android大廠面試祕籍,爲你保駕護航金三銀四,直通大廠

  10. 天下無難試之HTTP協議面試刁難大全(上)

  11. 聊一聊session和cookie

  12. 什麼是XSS攻擊,XSS攻擊能夠分爲哪幾類?如何防範XSS攻擊?

  13. 前端安全系列(一):如何防止XSS攻擊?

  14. 前端安全系列之二:如何防止CSRF攻擊?

  15. cookie 和 token 都存放在 header 中,爲何不會劫持 token

  16. 前端常見跨域解決方案(全)

  17. CORS 簡單請求+預檢請求

  18. CORS

  19. 跨域總結:從CORS到Ngnix

  20. 介紹下重繪和迴流(Repaint & Reflow),以及如何進行優化

相關文章
相關標籤/搜索