1. 程式人生 > >一次完整的瀏覽器請求流程

一次完整的瀏覽器請求流程

當我們在瀏覽器的位址列輸入 www.linux178.com ,然後回車,回車這一瞬間到看到頁面到底發生了什麼呢?
整個流程如下:

  • 域名解析 -->
  • 發起TCP的3次握手 -->
  • 建立TCP連線後發起http請求 -->
  • 伺服器響應http請求,瀏覽器得到html程式碼 -->
  • 瀏覽器解析html程式碼,並請求html程式碼中的資源(如js、css、圖片等) -->
  • 瀏覽器對頁面進行渲染呈現給使用者

以下就是上面過程的一一分析,我們就以Chrome瀏覽器為例:

域名解析

首先Chrome瀏覽器會解析 www.linux178.com 這個域名對應的IP地址。怎麼解析到對應的IP地址?
Chrome瀏覽器會首先搜尋瀏覽器自身的DNS快取

(快取時間比較短,大概只有1分鐘,且只能容納1000條快取)。
如果瀏覽器自身快取找不到則會檢視系統的DNS快取,如果找到且沒有過期則停止搜尋解析到此結束.
而如果本機沒有找到DNS快取,則瀏覽器會發起一個DNS的系統呼叫,就會向本地配置的首選DNS伺服器發起域名解析請求(通過的是UDP協議向DNS的53埠發起請求,這個請求是遞迴的請求,也就是運營商的DNS伺服器必須得提供給我們該域名的IP地址),運營商的DNS伺服器首先查詢自身的快取,找到對應的條目,且沒有過期,則解析成功。如果沒有找到對應的條目,則有運營商的DNS代我們的瀏覽器發起迭代DNS解析請求,它首先是會找根域的DNS的IP地址(這個DNS伺服器都內建13臺根域的DNS的IP地址),找打根域的DNS地址,就會向其發起請求(請問www.linux178.com這個域名的IP地址是多少啊?),根域發現這是一個頂級域com域的一個域名,於是就告訴運營商的DNS我不知道這個域名的IP地址,但是我知道com域的IP地址,你去找它去,於是運營商的DNS就得到了com域的IP地址,又向com域的IP地址發起了請求(請問www.linux178.com這個域名的IP地址是多少?),com域這臺伺服器告訴運營商的DNS我不知道www.linux178.com這個域名的IP地址,但是我知道linux178.com這個域的DNS地址,你去找它去,於是運營商的DNS又向linux178.com這個域名的DNS地址(這個一般就是由域名註冊商提供的,像萬網,新網等)發起請求(請問www.linux178.com這個域名的IP地址是多少?),這個時候linux178.com域的DNS伺服器一查,誒,果真在我這裡,於是就把找到的結果傳送給運營商的DNS伺服器,這個時候運營商的DNS伺服器就拿到了www.linux178.com這個域名對應的IP地址,並返回給Windows系統核心,核心又把結果返回給瀏覽器,終於瀏覽器拿到了www.linux178.com對應的IP地址,該進行一步的動作了。

發起TCP的3次握手

拿到域名對應的IP地址之後,User-Agent(一般是指瀏覽器)會以一個隨機埠(1024< 埠 < 65535)向伺服器的WEB程式(常用的有httpd,nginx等)80埠發起TCP的連線請求。這個連線請求(原始的http請求經過TCP/IP4層模型的層層封包)到達伺服器端後(這中間通過各種路由裝置,區域網內除外),進入到網絡卡,然後是進入到核心的TCP/IP協議棧(用於識別該連線請求,解封包,一層一層的剝開),還有可能要經過Netfilter防火牆(屬於核心的模組)的過濾,最終到達WEB程式(本文就以Nginx為例),最終建立了TCP/IP的連線。

為什麼HTTP協議要基於TCP來實現?

TCP是一個端到端的可靠的面向連線的協議,所以HTTP基於傳輸層TCP協議不用擔心資料的傳輸的各種問題

建立TCP連線後發起http請求

進過TCP3次握手之後,瀏覽器發起了http的請求,使用的http的方法 GET 方法,請求的URL是 / ,協議是HTTP/1.0


下面是第12號包的詳細內容:

3.png
3.png

以上的報文是HTTP請求報文。

那麼HTTP請求報文和響應報文會是什麼格式呢?

個HTTP請求報文由請求行(request line),請求頭部(header),
空行和請求資料4個部分組成
,下圖給出了請求報文的一般格式。

HTTP請求頭
HTTP請求頭
請求行

請求行由請求方法欄位、URL欄位和HTTP協議版本欄位3個欄位組成,它們用空格分隔。例如,GET /index.html HTTP/1.1。
HTTP協議的請求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。這裡介紹最常用的GET方法和POST方法。

  • GET:當客戶端要從伺服器中讀取文件時,使用GET方法。GET方法要求伺服器將URL定位的資源放在響應報文的資料部分,回送給客戶端。使用GET方法時,請求引數和對應的值附加在URL後面,利用一個問號(“?”)代表URL的結尾與請求引數的開始,傳遞引數長度受限制。例如,/index.jsp?id=100&op=bind。
  • POST:當客戶端給伺服器提供資訊較多時可以使用POST方法。POST方法將請求引數封裝在HTTP請求資料中,以名稱/值的形式出現,可以傳輸大量資料。
    請求頭部
    請求頭部由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。請求頭部通知伺服器有關於客戶端請求的資訊,典型的請求頭有:
    User-Agent:產生請求的瀏覽器型別。
    Accept:客戶端可識別的內容型別列表。
    Host:請求的主機名,允許多個域名同處一個IP地址,即虛擬主機。
    空行
    最後一個請求頭之後是一個空行,傳送回車符和換行符,通知伺服器以下不再有請求頭。
    請求資料
    請求資料不在GET方法中使用,而是在POST方法中使用。POST方法適用於需要客戶填寫表單的場合。與請求資料相關的最常使用的請求頭是Content-Type和Content-Length。
那麼起始行中的請求方法有哪些種呢?

GET: 完整請求一個資源 (常用)
HEAD: 僅請求響應首部
POST:提交表單 (常用)
PUT: 上傳
DELETE:刪除

那什麼是URL、URI、URN?

URI Uniform Resource Identifier 統一資源識別符號
URL Uniform Resource Locator 統一資源定位符 格式如下: scheme://[username:[email protected]]HOST:port/path/to/source http://www.magedu.com/downloads/nginx-1.5.tar.gzURN Uniform Resource Name 統一資源名稱URL和URN 都屬於 URI為了方便就把URL和URI暫時都通指一個東西

請求的協議有哪些種?
有以下幾種:
http/0.9: statelesshttp/1.0: MIME, keep-alive (保持連線), 快取http/1.1: 更多的請求方法,更精細的快取控制,持久連線(persistent connection) 比較常用

下面是Chrome發起的http請求報文頭部資訊

4.png
4.png

其中
Accept 就是告訴伺服器端,我接受那些MIME型別Accept-Encoding 這個看起來是接受那些壓縮方式的檔案Accept-Lanague 告訴伺服器能夠傳送哪些語言 Connection 告訴伺服器支援keep-alive特性Cookie 每次請求時都會攜帶上Cookie以方便伺服器端識別是否是同一個客戶端Host 用來標識請求伺服器上的那個虛擬主機,比如Nginx裡面可以定義很多個虛擬主機 那這裡就是用來標識要訪問那個虛擬主機。User-Agent 使用者代理,一般情況是瀏覽器,也有其他型別,如:wget curl 搜尋引擎的蜘蛛等 條件請求首部:If-Modified-Since 是瀏覽器向伺服器端詢問某個資原始檔如果自從什麼時間修改過,那麼重新發給我,這樣就保證伺服器端資源 檔案更新時,瀏覽器再次去請求,而不是使用快取中的檔案安全請求首部:Authorization: 客戶端提供給伺服器的認證資訊;

伺服器端響應http請求,瀏覽器得到html程式碼

伺服器端WEB程式接收到http請求以後,就開始處理該請求,處理之後就返回給瀏覽器html檔案。

5.png
5.png

第32號包 是伺服器返回給客戶端http響應包(200 ok 響應的MIME型別是text/html),代表這一次客戶端發起的http請求已成功響應。200 代表是的 響應成功的狀態碼,還有其他的狀態碼如下:
1xx: 資訊性狀態碼 100, 101
2xx: 成功狀態碼 200:OK
3xx: 重定向狀態碼
301: 永久重定向, Location響應首部的值仍為當前URL,因此為隱藏重定向;
302: 臨時重定向,顯式重定向, Location響應首部的值為新的URL
304:Not Modified 未修改,比如本地快取的資原始檔和伺服器上比較時,發現並沒有修改,伺服器返回一個304狀態碼, 告訴瀏覽器,你不用請求該資源,直接使用本地的資源即可。
4xx: 客戶端錯誤狀態碼
404: Not Found 請求的URL資源並不存在
5xx: 伺服器端錯誤狀態碼
500: Internal Server Error 伺服器內部錯誤
502: Bad Gateway 前面代理伺服器聯絡不到後端的伺服器時出現
504:Gateway Timeout 這個是代理能聯絡到後端的伺服器,但是後端的伺服器在規定的時間內沒有給代理伺服器響應

瀏覽器解析html程式碼,並請求html程式碼中的資源

瀏覽器拿到index.html檔案後,就開始解析其中的html程式碼,遇到js/css/image等靜態資源時,就向伺服器端去請求下載(會使用多執行緒下載,每個瀏覽器的執行緒數不一樣),這個時候就用上keep-alive特性了,建立一次HTTP連線,可以請求多個資源。

瀏覽器在請求靜態資源時(在未過期的情況下),向伺服器端發起一個http請求(詢問自從上一次修改時間到現在有沒有對資源進行修改),如果伺服器端返回304狀態碼(告訴瀏覽器伺服器端沒有修改),那麼瀏覽器會直接讀取本地的該資源的快取檔案。

10.png
10.png

瀏覽器對頁面進行渲染呈現給使用者

最後,瀏覽器利用自己內部的工作機制,把請求到的靜態資源和html程式碼進行渲染,渲染之後呈現給使用者。



文/lintong(簡書作者)
原文連結:http://www.jianshu.com/p/fbe0e9fa45a6
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。