從輸入URL到頁面加載 —— 網絡請求篇

https://juejin.im/post/5e57d5b7f265da57133b2af9html


前言

在Web相關的問題中,從輸入URL到整個頁面加載展現到用戶面前這個問題是繞不開的,它主要涉及到網絡請求與客戶端渲染兩個步驟數據庫

  1. 網絡請求
    1. DNS解析
    2. TCP鏈接創建
    3. SSL/TLS隧道創建(HTTPS)
    4. 發送HTTP請求
    5. 返回HTTP報文
    6. 斷開SSL/TLS隧道
    7. 關閉TCP鏈接
  2. 客戶端渲染

本文主要介紹一下其中的網絡請求部分。瀏覽器


DNS解析

相比較於IP地址,以字符串來表示的域名更加符合人類的記憶習慣,所以用戶一般使用域名來訪問資源,而非IP地址。DNS提供域名與IP的映射服務,解析用戶輸入的域名爲真實IP地址進行訪問。緩存

解析流程

  1. 首先瀏覽器會查詢自身的DNS緩存,此處緩存時間較短,Chrome只有1分鐘。
  2. 若是瀏覽器的緩存裏沒有找到的話,則搜索系統自身的DNS緩存。
  3. 瀏覽器若是在上述緩存裏沒有找到對應的條目,則查找本地Host文件,若是在Host文件中查找到對應的IP的話,則使用這個IP。
  4. 若是在上一步未命中,則向本地DNS服務器發起請求,查詢域名對應的IP地址。請求到達服務器後,DNS服務器會首先查詢緩存,若是命中,則返回IP地址
  5. 若是沒有找到的話,本地DNS服務器會以遞歸查詢的方式依次向根域名服務器、頂級域名服務器、權威域名服務器發起查詢請求,直到獲取到IP地址
  6. 本地DNS服務器會將IP地址返回給瀏覽器並存入緩存,方便下次查詢。

查詢流程

性能優化

DNS prefetch:在代碼中,常常將一些靜態資源放在CDN中,每一個CDN地址都要去作下DNS解析,這個會浪費時間,能夠經過預先進行DNS解析,而後在請求的時候,DNS已經解析完成就不用等待了。安全

<!--在head標籤中,放在前面-->
<link rel="dns-prefetch" href="//test.com">
複製代碼

TCP鏈接創建

TCP協議位於傳輸層,負責提供可靠的字節流服務。性能優化

字節流服務:爲了方便傳輸,將大塊數據分割成以報文段爲單位的數據包進行管理。服務器

可靠的傳輸服務:將數據準確可靠地傳輸給對方網絡

爲了確保數據傳輸服務的可靠性,TCP協議採用了三次握手策略:post

  1. 發送端首先發送一個帶有SYN標誌的數據包給接收端
  2. 接收端收到後,回傳一個帶有SYN/ACK標誌的數據包傳達確認信息
  3. 發送端再次回傳一個帶有ACK標誌的數據包,握手結束

若是上述過程當中某個階段中斷,則TCP協議會再次以相同的次序進行握手操做創建鏈接性能

三步握手的目的是讓兩方都確認對方可以發送接收數據:

  1. 發送端發出,接收端接收,接收端知道發送端能發送數據
  2. 接收端發出,發送端接收,發送端知道接收端能發送及接收數據
  3. 發送端發出,接收端接收,接收端知道發送端能接收數據

SSL/TLS隧道創建(HTTPS)

說到SSL/TLS須要首先介紹下HTTPS,HTTPS是加上了加密處理、認證機制以及完整性保護的HTTP,它並不是是應用層的一種新協議,而是將HTTP通訊接口部分使用SSL/TLS協議代替。一般,HTTP會直接和TCP進行通訊,而加上這部分處理後,則演變爲先和SSL/TLS通訊,再由SSL/TLS和TCP進行通訊了,至關於加了一層SSL/TLS外殼的HTTP。

SSL協議,是一種安全傳輸協議,最初是由 Netscape 在1996年發佈,因爲一些安全的緣由SSL v1.0和SSL v2.0都沒有公開,直到1996年的SSL v3.0。TLS是SSL v3.0的升級版,目前市面上全部的HTTPS都是用的是TLS,而不是SSL。

SSL/TLS是獨立於HTTP的協議,也能夠用於其餘應用層的協議上,具體的加密等功能本文不作深刻探討,在這裏講一下SSL/TLS隧道創建的過程(四次握手):

第一次握手

  1. 客戶端發送Client Hello報文開始TLS/SSL通訊。報文中包含客戶端支持的TLS/SSL的指定版本以及加密組件列表

第二次握手

  1. 服務端支持TLS/SSL通訊時,會返回Server Hello報文。裏面一樣包含支持的TLS/SSL的指定版本以及加密組件列表
  2. 服務端發送Certificate報文,報文中包含公開密鑰證書
  3. 服務端發送Server Hello Done報文通知客戶端,TLS/SSL初步握手協商結束

第三次握手

  1. 客戶端發送Client Key Exchange報文,報文中包含隨機密碼串,該報文使用第一次握手步驟3中的公開密鑰進行加密
  2. 客戶端繼續發送Change Cipher Spec報文,該報文負責告知後續通訊的加密密碼串方式
  3. 客戶端發送Finished報文,報文包含鏈接至今所有報文的總體校驗值。本次握手是否成功,要以服務器可否正確解密該報文爲判斷標準

第四次握手

  1. 服務端發送Change Cipher Spec報文
  2. 服務端發送Finished報文,SSL/TLS通訊隧道創建。後續開始發送HTTP請求

3UhLwQ.png


發送HTTP請求

HTTP協議屬於TCP/IP族協議,用於主機之間的網絡通訊。

緩存機制

首次請求

  1. HTTP首次發起請求時,會先由瀏覽器查看是否有緩存數據
  2. 在確認無緩存數據後向服務器發起請求
  3. 服務器會返回數據以及緩存規則,瀏覽器在接收後存儲緩存的數據以及相應的緩存規則

緩存機制下的請求

HTTP的緩存主要分爲兩種:

  • 強緩存:請求的資源在緩存中未過時時,不與服務器進行交互,直接使用緩存中的數據
  • 協商緩存:當強緩存過時未命中或者Cache-Control中有must-revalidate標識表示每次必須驗證資源狀態時,使用協商緩存去處理緩存文件。從緩存數據庫中取出緩存的標識,向服務器發送請求驗證請求的數據是否更新,若是已經更新則返回新的數據,若是未更新則使用緩存中的數據

總體流程

3UhLwQ.png

協議層傳輸過程

利用TCP/IP協議族進行網絡通訊時,會經過分層順序與對方進行通訊。發送端從應用層往下走,接收端則往應用層往上走。

  1. 首先做爲發送端的客戶端在應用層(HTTP協議)發出HTTP請求,獲取 Web 頁面
  2. 接着,爲了傳輸方便,在傳輸層(TCP 協議)把從應用層處收到的數據(HTTP 請求報文)進行分割,並在各個報文上打上標記序號及端口號後轉發給網絡層。
  3. 在網絡層(IP 協議),增長做爲通訊目的地的 MAC 地址後轉發給鏈路層。這樣一來,發往網絡的通訊請求就準備齊全了
  4. 接收端的服務器在鏈路層接收到數據,按序往上層發送,一直到應用層。當傳輸到應用層,才能算真正接收到由客戶端發送過來的 HTTP 請求。


返回HTTP報文

返回狀態碼標識請求結果

  • 2XX:請求被正常處理
  • 3XX:瀏覽器須要執行某些特殊的處理以正確處理請求
  • 4XX:客戶端發生錯誤,請求未能成功
  • 5XX:服務器端發生錯誤,請求未能成功

斷開SSL/TLS隧道

SSL/TLS隧道的斷開由客戶端發起,經過發送close_notify報文斷開

關閉TCP鏈接

在關閉鏈接時,TCP通訊雙方一共須要操做四次,稱爲四次揮手:

  1. 客戶端向服務端發送FIN標記的報文
  2. 服務端收到客戶端發送的報文後,發送一個包含確認序號ACK的報文
  3. 服務端向客戶端發送FIN標記報文
  4. 客戶端在收到FIN標記報文後,會向服務端發送確認序號ACK報文,而後通過兩個MSL時長後斷開鏈接

MSL(Maximum Segment Lifetime):最大報文生存時間,指報文發送和接收的最長時間

30DlY6.jpg

第二次揮手時,服務端可能還有數據報文須要發送,所以會先發送ACK報文告知客戶端已知悉要斷開請求,在處理完數據報文後會發送FIN報文給客戶端,這樣就保證了數據通訊的正常可靠性。

相關文章
相關標籤/搜索