浏览器发送http请求过程分析
https://segmentfault.com/a/1190000010156898
請求過程整體流程:
域名解析?-->?發起TCP的3次握手?-->?建立TCP連接后發起http請求?-->?服務器響應http請求,瀏覽器得到html代碼?-->?瀏覽器解析html代碼,并請求html代碼中的資源(如js、css、圖片等)?-->?瀏覽器對頁面進行渲染呈現給用戶.
下面以Chrome瀏覽器訪問?www.google.com?為例按流程逐個分析:
域名解析
Chrome瀏覽器會首先搜索瀏覽器自身的DNS緩存(緩存時間比較短,大概只有1分鐘,且只能容納1000條緩存),看自身的緩存中是否有?www.google.com?對應的條目,而且沒有過期,如果有且沒有過期則解析到此結束。
注:我們可以使用?chrome://net-internals/#dns?來進行查看Chrome自身的緩存。
如果瀏覽器自身的緩存里面沒有找到對應的條目,那么Chrome會搜索操作系統自身的DNS緩存,如果找到且沒有過期則停止搜索解析到此結束.
注:以Windows系統為例,可以在命令行下使用 ipconfig /displaydns 來進行查看操作系統自身的DNS緩存?
如果在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?-->?根域名服務器?-->?頂級域名服務器?-->?域名注冊商服務器
發起TCP的3次握手
拿到域名對應的IP地址之后,User-Agent(一般是指瀏覽器)會以一個隨機端口(1024 < 端口 < 65535)向服務器的WEB程序(常用的有httpd,nginx等)80端口發起TCP的連接請求。這個連接請求(原始的http請求經過TCP/IP4層模型的層層封包)到達服務器端后(這中間通過各種路由設備,局域網內除外),進入到網卡,然后是進入到內核的TCP/IP協議棧(用于識別該連接請求,解封包,一層一層的剝開),還有可能要經過Netfilter防火墻(屬于內核的模塊)的過濾,最終到達WEB程序,最終建立了TCP/IP的連接。
三次握手抓包截圖:
建立TCP連接后發起http請求
進過TCP3次握手之后,瀏覽器發起了http的請求,使用的http的方法 GET 方法,請求的URL是 / ,協議是HTTP/1.1
http請求報文格式
服務器端響應http請求,瀏覽器得到html代碼
http響應報文格式
http狀態碼
| 1** | 信息,服務器收到請求,需要請求者繼續執行操作 |
| 2** | 成功,操作被成功接收并處理 |
| 3** | 重定向,需要進一步的操作以完成請求 |
| 4** | 客戶端錯誤,請求包含語法錯誤或無法完成請求 |
| 5** | 服務器錯誤,服務器在處理請求的過程中發生了錯誤 |
瀏覽器解析html代碼,并請求html代碼中的資源
瀏覽器拿到index.html文件后,就開始解析其中的html代碼,遇到js/css/image等靜態資源時,就向服務器端去請求下載(會使用多線程下載,每個瀏覽器的線程數不一樣),這個時候就用上keep-alive特性了,建立一次HTTP連接,可以請求多個資源,下載資源的順序就是按照代碼里的順序,但是由于每個資源大小不一樣,而瀏覽器又多線程請求請求資源,所以顯示的順序并不一定是代碼里面的順序。
瀏覽器在請求靜態資源時(在未過期的情況下),向服務器端發起一個http請求(詢問自從上一次修改時間到現在有沒有對資源進行修改),如果服務器端返回304狀態碼(告訴瀏覽器服務器端沒有修改),那么瀏覽器會直接讀取本地的該資源的緩存文件。
詳細的瀏覽器工作原理請看:http://kb.cnblogs.com/page/12...
瀏覽器對頁面進行渲染呈現給用戶
最后,瀏覽器利用自己內部的工作機制,把請求到的靜態資源和html代碼進行渲染,渲染之后呈現給用戶。
參考文獻:
一次完整的HTTP事務是怎樣一個過程?
百科 - HTTP頭字段
轉載于:https://www.cnblogs.com/davidwang456/articles/10668744.html
總結
以上是生活随笔為你收集整理的浏览器发送http请求过程分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 邮件协议(SMTP)性能测试总结(Fox
- 下一篇: 一文读懂HTTP/2 及 HTTP/3特