請求一個url的全過程


最近在進行前端面試方面的一些准備,遇到了一個經典前端問題,一個url從輸入到頁面加載中間到底發生了什么,以前也認真想過這個問題,但是當時回答的都不全面,現在來好好總結一下:

總體來說分為以下六個步驟:

1、DNS解析

2、TCP連接

3、發送HTTP請求

4、服務器處理請求並返回HTTP報文

5、瀏覽器解析渲染頁面

6、連接結束

具體過程:

1、DNS解析

DNS解析的過程就是尋找哪台服務器上有我請求資源的過程,當你在瀏覽器中輸入一個地址時,例如:www.baidu.com,其實並不是百度網站真正意義上的地址,互聯網上每一台計算機的唯一標識是他的IP地址,但是IP地址並不方便記憶,所以互聯網設計者需要在用戶的方便性與可用性方面做一個權衡,這個權衡就是一個網址到ip地址的轉換,這個過程就是DNS解析,就是域名到ip地址的轉換

DNS解析是一個遞歸查詢的過程

例如你在瀏覽器中輸入一個www.google.com的IP地址,首先在本地域名服務器中查詢IP地址,如果沒有找到,本地域名服務器會向根域名服務器發送一個請求,如果根域名服務器也不存儲該域名,本地域名會向com頂級域名服務器發送一個請求,依次類推下去,直到最后本地域名服務器得到google的IP地址並把它緩存到本地,供下次查詢使用(自己計算機上的hosts文件就是域名到ip的一個映射,他可以不用去尋找網絡上的DNS解析),,從上述過程中,可以看出網址的解析是一個從右到左的過程:com->google.com->www.google.com,但是你是否發現少了點什么,根域名服務器的解析過程呢?實際上,真正的網址是www.google.com,並不是我多打開一個.,這個.對應的就是根域名服務器,默認情況下所有的網址的最后一位都是.,即然是默認情況下,為了方便用戶,通常都會省略,瀏覽器在請求DNS的時候會自動加上去,所有的網址真正解析的過程為.->.com->google.com->www.google.com

DNS優化

為了了解DNS的過程,可以為我們帶來什么?上文中請求道google的ip地址,經歷了8個步驟,這個步驟中存在多個請求(同時存在UDP和TCP請求),為什么有兩種請求方式呢)如果每次都經過這么多步驟,是否太耗時間,如何減少該過程的步驟呢,那就是DNS緩存

DNS緩存

DNS存在着多級緩存,從離瀏覽器的距離排序的話,有以下幾種:瀏覽器緩存,系統緩存,路由緩存,IPS服務器緩存,根域名服務器緩存,頂級域名服務器緩存,主域名服務器緩存

在你的chrome瀏覽器中輸入:chrome://dns/,你就可以看到chrome瀏覽器的DNS緩存

系統緩存主要存在hosts文件中

DNS負載均衡

不知道大家有沒有思考過一個問題,DNS返回的IP地址石佛偶每次都一樣呢?如果每次都一樣是否說明你請求的資源都位於同一台機器上面,那么這台服務器需要多高的性能和存儲才能滿足億萬請求呢?其實真是的互聯網世界背后存在成千上百的服務器,大型的網站甚至更多,在用戶眼里,它需要的只是處理它的請求,哪台服務器處理並不重要。DNS可以返回一個合適的機器的IP給用戶,例如可以根據每台服務器的負載量,該機器離用戶地理位置的距離等,這種過程就是DNS負載均衡,又可以叫做DNS重定向,大家耳熟能詳的CDN就是利用DNS的重定向技術,DNS服務器會返回一個跟用戶最接近的點的IP地址給用戶,CDN節點的服務器負責響應用戶的請求,提供所需的內容。

2、TCP連接

HTTP協議是使用TCP作為其傳輸層協議的,當TCP出現瓶頸時,HTTP也會受到影響

3、HTTP協議

HTTP報文是包裹在TCP報文中發送的,服務器端收到TCP報文時會解包提取出HTTP報文,但是這個過程存在一定風險,HTTP報文時明文,如果中間被截取的話存在一些信息泄露的風險,那么在進入TCP報文之前對HTTP做一次加密就可以解決這個問題了,HTTPS協議的本質就是HTTP+SSL(or TLS)。在HTTP報文進入到TCP報文之前,先使用SSL對HTTP報文進行加密,從網絡層結構看他位於HTTP協議與TCP協議之間。

HTTPS過程

HTTPS在傳輸數據之前需要客戶端與服務器進行一個握手(TLS/SSL握手),在握手過程中將確立雙方加密傳輸數據的密碼信息,TLS/SSL使用了非對稱加密,對稱加密及hash等,HTTPS相比HTTP,雖然提供了安全保證,但是也勢必會帶來一些時間上的損耗,如握手和加密過程等,是否使用HTTPS需要根據具體情況在安全和性能方面做權衡。

HTTP請求

發送HTTP請求的過程就是構建HTTP請求報文並通過TCP協議中發送到服務器指定端口(HTTP協議是80/8080,HTTPS端口是443).HTTP請求報文由三部分組成:請求行,請求報頭,請求正文。

請求行

格式如下:

Method Request-URL HTTP-Version CRLF

eg:GET index.html HTTP/1.1

常用的方法有:GET,POST,PUT,DELETE,OPTIONS,HEAD

請求抱頭

請求報頭允許客戶端向服務器傳遞請求的附加信息和客戶端自身的信息。客戶端並不一定特指瀏覽器,有時候也可以使用測試工具等

常見的請求報頭有:Accept,Accept-Charset,Accept-Endding,Accept-Language,Content-Type,Authorization,Cookie,User-Agent等。

Accept用於指定客戶端用於接受哪些類型的信息,Accept-Encoding與Accept類似,它用於指定接受的編碼方式。Connection設置為Keep-alive用於告訴客戶端本次HTTP請求結束之后並不需要關閉TCP連接,這樣可以使下次HTTP請求使用相同的TCP通道,節省TCP連接建立的時間。

請求正文

當使用POST、put等方法時,通常需要客戶端向服務器傳遞數據,這些數據就存儲在請求正文中,在請求包文中有一些與請求正文相關的信息,請求的數據格式一般為json,這時就需要設置Content-Type:application/json.

4、服務器處理請求並返回HTTP報文

這些就是后端工程師眼中的HTTP,后端從固定的端口接收到TCP報文開始,這一部分對應編程語言中的socket。它對TCP連接進行處理,對HTTP協議進行解析,並按照報文格式進一步封裝成HTTP Request對象,供上層使用,這一部分工作一般是由WEB服務器去進行,我們使用過的W惡霸服務器又Tomcat等

http響應報文也是由散步分組成的狀態碼、響應報頭、響應報文

狀態碼:

狀態碼是由三個數字組成的,第一個數字定義了響應的類別,且有5種可能取值:

1xx:指示信息-表示請求已接收,繼續處理

2xx:成功-表示請求已被成功接收

3xx:重定向-要完成請求必須進行更進一步的操作

4xx:客戶端錯誤-請求的語法錯誤或請求無法實現

5xx:服務器端錯誤--服務器未能實現合法的請求。

響應報文:

服務器返回給瀏覽器的文本信息,通常HTML、css、js、圖片等文件就放在這一部分

5、瀏覽器解析渲染頁面

瀏覽器收到HTML\CSS\JS文件后,它是如何把頁面呈現到屏幕上的?

瀏覽器是一個邊解析邊渲染的過程。首先瀏覽器解析HTML文件構建DOM樹,然后解析CSS文件構建渲染樹,等到渲染樹構建完成后,瀏覽器開始布局渲染樹並將其繪制到屏幕上,這個過程比較復雜,設計到兩個概念:reflow回流和repain重繪。DOM節點中的各個元素都是以盒模型的形式存在的,這些都需要瀏覽器去計算其位置和大小等,這個過程稱為relow,當盒模型的位置大小和其他屬性,顏色,字體確定下來之后,瀏覽器便開始繪制內容了,這個過程稱為repain,頁面在首次加載時必然會經歷reflow和repain。這個過程是非常消耗性能的,尤其是在移動設備上,他會破壞用戶體驗,有時會造成頁面卡頓,所以我們盡可能減少reflow和repain。

js解析是由瀏覽器中的js解析引擎完成的,js是單線程運行,也就是說,在同一個時間內只能做一件事,所有的任務都需要排隊,前一個任務結束,后一個任務才開始,但是又存在某些任務比較耗時,如IO讀寫,所以需要一種機制可以先執行排在后面的任務,這就是:同步任何和異步任務,js的執行機制可以看作是一個主線程加上一個任務隊列,同步任務就是放在主線程上執行的任務,異步任務是放在任務隊列中的任務。所有的同步任務在主線程上執行,形成一個執行棧,異步任務有了運行結果就會在任務隊列中放置一個事件;腳本運行時先依次運行執行棧,然后會從任務隊列里提取事件,運行任務隊列中的任務,這個過程是不斷重復的,所以又叫事件循環。

瀏覽器在解析過程中,如果遇到請求外部資源的時候,如圖像、js文件\css文件deng ,瀏覽器將下載該資源,請求過程是異步的,並不會影響html文檔進行加載,但是當文檔加載過程中遇到js文件時,html文檔會掛起渲染過程,不僅要等到文檔中js文件加載完畢還要等待解析執行完畢,才會繼續html的渲染過程,原因是因為js有可能會修改dom結構,這意味着js執行完成前,后續所有資源下載是沒有必要的,這就是js阻塞后續資源下載的根本原因,css文件的加載不影響js文件的加載,但是卻影響js文件的執行,js代碼執行前瀏覽器必須保證css文件已經下載並加載完畢,這也是在head中為什么先用link引用css文件,再去加載js文件的原因.

web優化

了解上面過程的目的就是為了Web優化,在談到Web優化之前,我們回到一個更原始的問題,Web前端的本質是什么?我的理解是:將信息快速並友好的展示給用戶並能夠與用戶進行交互,快速的意思就是在盡可能短的時間內完成頁面的加載,試想一下如果你在淘寶購買東西的時候,淘寶頁面加載十幾秒才顯示出物品,這個時候你還有心情去購物嗎?怎么快速完成頁面的加載呢?最簡單的答案就是參照雅虎34條軍規,這34條軍規實際上就是圍繞請求過程進行的一些優化方式。

如何盡快地加載資源呢?答案就是不能從網路中加載的資源就不從網路中加載,當我們合理使用緩存,將資源放在瀏覽器端,這是最快的方式,如果資源必須從網絡中獲取,則要考慮縮短連接時間,即DNS優化部分,減少響應內容大小,即對內容進行壓縮。另一方面,如果加載的資源數比較少的話,額可以快速的響應用戶,當資源到達瀏覽器之后,瀏覽器開始盡心那個解析渲染,瀏覽器中最耗時間的就是reflow,所以圍繞這一部分可以澳旅如何減少reflow的次數。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM