天天看點

從輸入url到頁面完成加載發生了什麼(完結)

在寫這篇文章之前本想着這個知識點涉及知識點太多太雜,我自己又是一個計算機網絡小白找一篇大牛寫的看看就算了,但是看了大概七八篇後,内心更糾結了——???真的好雜。。。記憶點找不到了,搞的心裡亂亂的,大概是糾結症犯了。是以還是動手總結一下,讓自己有個可以抓取的記憶點,也讓自己對這個知識點有個淺顯的認知。本文旨在講述發生的流程,其中穿插的知識點及概念我會放到小框裡或者貼參考連結。

先來個流程總述:

  • DNS解析:将域名解析成IP位址
  • TCP連接配接:TCP三向交握
  • 發送HTTP請求
  • 伺服器處理請求并傳回HTTP封包
  • 浏覽器解析渲染頁面
  • 連接配接結束:TCP四次揮手

1、DNS解析

在浏覽器輸入URL後,首先要經過域名解析。浏覽器通過向 DNS 伺服器發送域名,DNS 伺服器查詢到與域名相對應的 IP 位址,然後傳回給浏覽器,浏覽器再将 IP 位址打在協定上,同時請求參數也會在協定搭載,然後一并發送給對應的伺服器。

1.什麼是URL

URL(Uniform Resource Locator),統一資源定位符,用于定位網際網路上資源,俗稱網址。比如 http://www.w3school.com.cn/ht…,遵守以下的文法規則:

scheme://host.domain:port/path/filename

各部分解釋如下:

scheme - 定義網際網路服務的類型。常見的協定有 http、https、ftp、file,其中最常見的類型是 http,而 https 則是進行加密的網絡傳輸。

host - 定義域主機(http 的預設主機是 www)

domain - 定義網際網路域名,比如 w3school.com.cn

port - 定義主機上的端口号(http 的預設端口号是 80)

path - 定義伺服器上的路徑(如果省略,則文檔必須位于網站的根目錄中)。

filename - 定義文檔/資源的名稱

2. 什麼是DNS

DNS(domain name system,域名系統):網際網路上域名和IP位址互相映射的分布式資料庫;簡單了解就是域名與IP位址的對照表,因為域名(如:www.google.com)對于我們而言,更便于記憶,但是機器卻不擅長這種表達方式,是以需要将域名轉換為IP位址,以便于機器識别, 這便有了DNS。

3. 根域名伺服器

根伺服器是架設網際網路的必須設施,管理網際網路的主目錄,全球共有13套根域名伺服器

4. 遞歸查詢

用戶端主機向本地域名伺服器的查詢是遞歸查詢;所謂遞歸查詢:用戶端主機查詢的域名位址無法在本地域名伺服器中找到,是以本地域名伺服器就以DNS用戶端的身份向其他根域名伺服器發起請求,進行查詢,而不是讓用戶端主機去一直查詢;

遞歸查詢的結果要麼是傳回的IP位址,要麼是報錯,表示無法查詢到位址;

5. 疊代查詢

本地域名伺服器向根伺服器、頂級域名伺服器和主機域名伺服器發起的查詢請求就是疊代的過程,如:本地域名伺服器向根伺服器發起查詢請求,根伺服器中會告訴本地域名伺服器:”我這裡沒有你要找的内容,你去頂級域名伺服器上找吧“,并将頂級域名伺服器的位址傳回給本地域名伺服器,本地域名伺服器接收到後,繼續向頂級域名伺服器發送請求;頂級域名伺服器要麼傳回ip位址,要麼告訴本地域名伺服器下一步要向哪個權限域名伺服器發送請求,直到找到ip位址或找不到ip傳回報錯資訊,然後資訊傳回給用戶端主機;

下圖給出了這兩種查詢的差别

遞歸過程: 主機→本地DNS伺服器→其他DNS伺服器(如:我要找一個蘋果吃,找到了A,問A有沒有,A說我幫你去找B,B可能有,果真B有,然後B将蘋果給了A,A再将蘋果給我,這就是遞歸)

疊代過程: 本地DNS伺服器→根伺服器,本地DNS伺服器→頂級域名伺服器,本地DNS伺服器→權限域名伺服器;(如:我要找一個蘋果,找到了A,A說我也沒有,B可能有,你去找B吧;我又找B,B說我也沒有,你去找C吧,我又去找C,終于找到了蘋果,這就是疊代的過程)

2、TCP連接配接:TCP三向交握

在用戶端發送資料之前會發起 TCP 三次握手用以同步用戶端和服務端的序列号和确認号,并交換 TCP 視窗大小資訊。

從輸入url到頁面完成加載發生了什麼(完結)
  • 第一次握手:用戶端A将标志位SYN置為1,随機産生一個值為seq=X(X的取值範圍為=1234567)的資料包到伺服器,用戶端A進入SYN_SENT狀态,等待服務端B确認(第一次握手,由浏覽器發起,告訴伺服器我要發送請求了);
  • 第二次握手:服務端B收到資料包後由标志位SYN=1知道用戶端A請求建立連接配接,服務端B将标志位SYN和ACK都置為1,ack=X+1,随機産生一個值seq=Y,并将該資料包發送給用戶端A以确認連接配接請求,服務端B進入SYN_RCVD狀态(第二次握手,由伺服器發起,告訴浏覽器我準備接受了,你趕緊發送吧)。
  • 第三次握手:用戶端A收到确認後,檢查ack是否為X+1,ACK是否為1,如果正确則将标志位ACK置為1,ack=Y+1,并将該資料包發送給服務端B,服務端B檢查ack是否為Y+1,ACK是否為1,如果正确則連接配接建立成功,用戶端A和服務端B進入ESTABLISHED狀态,完成三次握手,随後用戶端A與服務端B之間可以開始傳輸資料了(第三次握手,由浏覽器發送,告訴伺服器,我馬上就發了,準備接受吧)。

為什需要三次握手?

計算機網絡》第四版中講“三次握手”的目的是“為了防止已失效的連接配接請求封包段突然又傳送到了服務端,因而産生錯誤”。 書中的例子是這樣的,“已失效的連接配接請求封包段”的産生在這樣一種情況下:client發出的第一個連接配接請求封包段并沒有丢失,而是在某個網絡結點長時間的滞留了,以緻延誤到連接配接釋放以後的某個時間才到達server。本來這是一個早已失效的封包段。但server收到此失效的連接配接請求封包段後,就誤認為是client再次發出的一個新的連接配接請求。于是就向client發出确認封包段,同意建立連接配接。

假設不采用“三次握手”,那麼隻要server發出确認,新的連接配接就建立了。由于現在client并沒有發出建立連接配接的請求,是以不會理睬server的确認,也不會向server發送資料。但server卻以為新的運輸連接配接已經建立,并一直等待client發來資料。這樣,server的很多資源就白白浪費掉了。采用“三次握手”的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的确認發出确認。server由于收不到确認,就知道client并沒有要求建立連接配接。”。主要目的防止server端一直等待,浪費資源。

3、浏覽器向web伺服器發送HTTP請求

TCP三向交握之後,開始發送HTTP請求封包至伺服器(關于HTTP請求封包詳解,我單獨寫了一篇☞傳送門)

HTTP請求封包格式:請求行+請求頭+空行+消息體,請求行包括請求方式(GET/POST/DELETE/PUT)、請求資源路徑(URL)、HTTP版本号;

從輸入url到頁面完成加載發生了什麼(完結)

4、伺服器處理請求并傳回HTTP封包

伺服器收到請求後會發出應答,即響應資料。HTTP響應與HTTP請求相似,

HTTP響應封包格式:狀态行+響應頭+空行+消息體,狀态行包括HTTP版本号、狀态碼、狀态說明。

從輸入url到頁面完成加載發生了什麼(完結)

5、浏覽器解析渲染頁面(關于渲染詳解我也單獨拎出來了☞傳送門)

浏覽器拿到響應文本後,解析HTML代碼,請求js,css等資源,最後進行頁面渲染,呈現給使用者。頁面渲染一般分為以下幾個步驟:

(1)根據HTML檔案解析出DOM Tree

(2)根據CSS解析出 CSSOM Tree(CSS規則樹)

(3)将 DOM Tree 和 CSSOM Tree合并,建構Render tree(渲染樹)

(4)reflow(重排):根據Render tree進行節點資訊計算(Layout)

(5)repaint(重繪):根據計算好的資訊繪制整個頁面(Painting)

6、TCP四次揮手。

當資料傳輸完畢,需要斷開TCP連接配接,此時發起tcp四次揮手

從輸入url到頁面完成加載發生了什麼(完結)

1、發起方向被動方發送封包,Fin、Ack、Seq,表示已經沒有資料傳輸了。并進入 FIN_WAIT_1 狀态。(第一次揮手:由浏覽器發起的,發送給伺服器,我請求封包發送完了,你準備關閉吧)

2、被動方發送封包,Ack、Seq,表示同意關閉請求。此時主機發起方進入 FIN_WAIT_2 狀态。(第二次揮手:由伺服器發起的,告訴浏覽器,我請求封包接受完了,我準備關閉了,你也準備吧)

3、被動方向發起方發送封包段,Fin、Ack、Seq,請求關閉連接配接。并進入 LAST_ACK 狀态。(第三次揮手:由伺服器發起,告訴浏覽器,我響應封包發送完了,你準備關閉吧)

4、發起方向被動方發送封包段,Ack、Seq。然後進入等待 TIME_WAIT 狀态。被動方收到發起方的封包段以後關閉連接配接。發起方等待一定時間未收到回複,則正常關閉。(第四次揮手:由浏覽器發起,告訴伺服器,我響應封包接受完了,我準備關閉了,你也準備吧)

簡單說就是:

1、A——>B :A告訴B:“我發完了”;

2、B——>A:B告訴A:“好的,我知道你發完了”

3、B——>A:B告訴A:“我收完了”;

4、A——>B:A告訴B:“好的,我知道你發收完了”

繼續閱讀