請求過程總體流程:域名解析
--> 發起TCP的3次握手
--> 創建TCP鏈接後發起http請求
--> 服務器響應http請求,瀏覽器獲得html代碼
--> 瀏覽器解析html代碼,並請求html代碼中的資源(如js、css、圖片等)
--> 瀏覽器對頁面進行渲染呈現給用戶
.
下面以Chrome瀏覽器訪問 www.google.com
爲例按流程逐個分析:css
Chrome瀏覽器會首先搜索瀏覽器自身的DNS緩存
(緩存時間比較短,大概只有1分鐘,且只能容納1000條緩存),看自身的緩存中是否有 www.google.com
對應的條目,並且沒有過時,若是有且沒有過時則解析到此結束。html
注:咱們可使用
chrome://net-internals/#dns
來進行查看Chrome自身的緩存。linux
若是瀏覽器自身的緩存裏面沒有找到對應的條目,那麼Chrome會搜索操做系統自身的DNS緩存
,若是找到且沒有過時則中止搜索解析到此結束.nginx
注:以Windows系統爲例,能夠在命令行下使用 ipconfig /displaydns 來進行查看操做系統自身的DNS緩存
chrome
若是在Windows系統的DNS緩存也沒有找到,那麼嘗試讀取hosts文件(位於C:\Windows\System32\drivers\etc),看看這裏面有沒有該域名對應的IP地址,若是有則解析成功。瀏覽器
若是在hosts
文件中也沒有找到對應的條目,瀏覽器就會發起一個DNS的系統調用,就會向本地配置的首選DNS服務器(通常是電信運營商提供的,也可使用像Google提供的DNS服務器)發起域名解析請求(經過的是UDP協議向DNS的53端口發起請求,這個請求是遞歸的請求,也就是運營商的DNS服務器必須得提供給咱們該域名的IP地址),運營商的DNS服務器首先查找自身的緩存,找到對應的條目,且沒有過時,則解析成功。若是沒有找到對應的條目,則有運營商的DNS代咱們的瀏覽器發起迭代DNS解析請求,它首先是會找根域的DNS的IP地址(這個DNS服務器都內置13臺根域的DNS的IP地址),找打根域的DNS地址,就會向其發起請求(請問 www.google.com
這個域名的IP地址是多少啊?),根域發現這是一個頂級域com域的一個域名,因而就告訴運營商的DNS我不知道這個域名的IP地址,可是我知道com域的IP地址,你去找它去,因而運營商的DNS就獲得了com域的IP地址,又向com域的IP地址發起了請求(請問www.google.com
這個域名的IP地址是多少?),com域這臺服務器告訴運營商的DNS我不知道www.google.com
這個域名的IP地址,可是我知道www.google.com
這個域的DNS地址,你去找它去,因而運營商的DNS又向www.google.com
這個域名的DNS地址(這個通常就是由域名註冊商提供的,像萬網,新網等)發起請求(請問www.google.com
這個域名的IP地址是多少?),這個時候www.google.com
域的DNS服務器一查,誒,果然在我這裏,因而就把找到的結果發送給運營商的DNS服務器,這個時候運營商的DNS服務器就拿到了www.google.com
這個域名對應的IP地址,並返回給Windows系統內核,內核又把結果返回給瀏覽器,終於瀏覽器拿到了www.google.com
對應的IP地址,該進行一步的動做了。運營商dns
--> 根域名服務器
--> 頂級域名服務器
--> 域名註冊商服務器
緩存
拿到域名對應的IP地址以後,User-Agent(通常是指瀏覽器)會以一個隨機端口(1024 < 端口 < 65535)向服務器的WEB程序(經常使用的有httpd,nginx等)80端口發起TCP的鏈接請求。這個鏈接請求(原始的http請求通過TCP/IP4層模型的層層封包)到達服務器端後(這中間經過各類路由設備,局域網內除外),進入到網卡,而後是進入到內核的TCP/IP協議棧(用於識別該鏈接請求,解封包,一層一層的剝開),還有可能要通過Netfilter防火牆(屬於內核的模塊)的過濾,最終到達WEB程序,最終創建了TCP/IP的鏈接。服務器
三次握手抓包截圖:多線程
進過TCP3次握手以後,瀏覽器發起了http的請求,使用的http的方法 GET 方法,請求的URL是 / ,協議是HTTP/1.1google
分類 | 分類描述 |
---|---|
1** | 信息,服務器收到請求,須要請求者繼續執行操做 |
2** | 成功,操做被成功接收並處理 |
3** | 重定向,須要進一步的操做以完成請求 |
4** | 客戶端錯誤,請求包含語法錯誤或沒法完成請求 |
5** | 服務器錯誤,服務器在處理請求的過程當中發生了錯誤 |
瀏覽器拿到index.html文件後,就開始解析其中的html代碼,遇到js/css/image等靜態資源時,就向服務器端去請求下載(會使用多線程下載,每一個瀏覽器的線程數不同),這個時候就用上keep-alive特性了,創建一次HTTP鏈接,能夠請求多個資源,下載資源的順序就是按照代碼裏的順序,可是因爲每一個資源大小不同,而瀏覽器又多線程請求請求資源,因此顯示的順序並不必定是代碼裏面的順序。
瀏覽器在請求靜態資源時(在未過時的狀況下),向服務器端發起一個http請求(詢問自從上一次修改時間到如今有沒有對資源進行修改),若是服務器端返回304狀態碼(告訴瀏覽器服務器端沒有修改),那麼瀏覽器會直接讀取本地的該資源的緩存文件。
詳細的瀏覽器工做原理請看:http://kb.cnblogs.com/page/12...
最後,瀏覽器利用本身內部的工做機制,把請求到的靜態資源和html代碼進行渲染,渲染以後呈現給用戶。