面試之 一個頁面從輸入url到頁面載入顯示完成,中間都經歷了什麼

junyu-node發表於2018-08-13
面試之 一個頁面從輸入url到頁面載入顯示完成,中間都經歷了什麼
隨著前端越來越成熟,前端的面試也越來越深入,面試就會經常問道一些和後臺有些關係的問題,比如經常 見到的 當你在頁面輸入一個url到頁面載入顯示完成,中間都經歷了什麼?結果也就那麼幾個過程,百度一下你會發現有很多答案。 整體的過程大概就是一下幾種
  • DNS域名解析
  • TCP連線
  • HTTP請求
  • 處理請求返回的HTTP響應
  • 頁面渲染

前端呢主要了解http請求,處理請求返回的HTTP響應和頁面渲染這一塊的內容,別的呢 我們一筆略過 ,大約知道這裡邊發生什麼事就可以了

DNS域名解析

首先我們要知道的是輸入位址列的域名並不是資源真實的位置,通過域名與ip地址的對映 找到資源的真實地址。
複製程式碼

TCP連線 通過第一步把伺服器的ip地址拿到 獲取到ip地址後便開始建立連線 完成三次握手。

http請求 tcp建立連線以後 發起一個http請求, 客戶端向伺服器發起的http 請求的時候 請求資訊包括三個部分 請求方法URI協議/版本 請求頭 請求正文 。請求方法(一般瀏覽器發起GET 或者POST請求)當然還包括 PUT DELETE HEAD OPTION TREANE 方法

那麼我們先看一個http的請求的例子
複製程式碼
//請求的方法協議版本
GET/sample.jspHTTP/1.1 
//請求頭
Accept:image/gif.image/jpeg,*/* //
Accept-Language:zh-cn   //
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
//請求正文
username=jinqiao&password=1234


複製程式碼

對於請求的協議版本 沒有什麼好說的 就是幾個固定的 http的版本 0.9 1.0 1.1 2.0

0.9 版本是http協議的第一個版本 已過時 它的組成及其簡單  只允許客戶發一個GET請求,不支援協議頭, 造成0.9版本支援一種內容 純文字

1.0版本 http的第二個版本, 第一個在通訊中指定版本號的http協議版本 至今被官方採用 相對於0.9 還加了一下主要特性
- 支援請求與響應頭
- 響應物件以一個響應狀態行開始
- 響應物件不限於超文字
- 開始支援客戶端其他請求方法 POST PUT 等
- 支援長連結(但預設還是用的短連結) 快取機制 及 身份認證

1.1 版本  是目前使用最廣泛的協議版本 與1.0最大的區別就是預設支援長連結,而且1.1開始支援host 域 新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法

2.0 支援多路複用  做到一個連線併發處理多個請求 二輕併發的數量比1.1 大好幾個數量級
複製程式碼

請求頭包含許多有關客戶環境和請求正文有用的資訊。 下邊我們就說幾個常用的請求頭

首部欄位名 說明
Accept 使用者代理可處理的媒體型別
Content-Encoding 實體的編碼方式
Content-Encoding 實體的編碼方式
Content-Language 實體的自然語言
Content-Range 實體的位置範圍
Content-Type 實體主體的媒體型別
Expires 實體過期時間
Last-Modified 資源的最後修改時間

前端 上傳圖片的時候 就會設定 上傳實體主體的媒體型別為 multiparty/form-data 這樣才能上傳圖片,另外 在用node 設定可以跨域訪問的時候設定4個header頭可以做到跨域

    Access-Control-Allow-Origin: http://foo.example //允許跨域的 域名  所有都允許可以用萬用字元 * 做值
    Access-Control-Allow-Methods: POST, GET, OPTIONS //允許跨域的方法
    Access-Control-Allow-Headers: X-PINGOTHER, Content-Type //  首部欄位用於預檢請求的響應。其指明瞭實際請求中允許攜帶的首部欄位。


    Access-Control-Max-Age: 86400 //請求的結果能夠別快取多久

複製程式碼

接下來就是處理請求返回的HTTP響應 響應資訊也是三個部分構成 狀態行 響應頭 響應體

狀態行 例如 HTTP/1.1 200 OK

其中200 是狀態碼 Status-code 200 1.1 是版本 。說到狀態碼 就不得不提經常面試的狀態碼了

200 OK 客戶端發過來的資料被正常處理
204 Not Content 正常響應,沒有實體
206 Partial Content 範圍請求,返回部分資料,響應報文中由Content-Range指定實體內容
301 (Moved Permanently) 永久重定向
302 (Found) 臨時重定向,規範要求方法名不變,但是都會改變
303 (See Other) 和302類似,但必須用GET方法
304 (Not Modified) 狀態未改變 配合(If-Match、If-Modified-Since、If-None_Match、If-Range、If-Unmodified-Since)
307 (Temporary Redirect) 臨時重定向,不該改變請求方法
400 (Bad Request) 請求報文語法錯誤
401 (unauthorized) 需要認證
403 (Forbidden) 伺服器拒絕訪問對應的資源
404 (Not Found) 伺服器上無法找到資源
500 (Internal Server Error)伺服器故障
503 (Service Unavailable) 伺服器處於超負載或正在停機維護

響應頭主要由Cache-Control、 Connection、Date、Pragma等組成。

響應體為伺服器返回給瀏覽器的資訊,主要由HTML,css,js,圖片檔案組成

說到響應,就繞不過一個快取的問題 那麼我們根據這張圖簡單分析一下片 http的快取機制 面試之 一個頁面從輸入url到頁面載入顯示完成,中間都經歷了什麼

Expires 指快取過期的時間,超過了這個時間點就代表資源過期。有一個問題是由於使用具體時間,如果時間表示出錯或者沒有轉換到正確的時區都可能造成快取生命週期出錯。並且 Expires 是 HTTP/1.0 的標準,現在更傾向於用 HTTP/1.1 中定義的 Cache-Control。兩個同時存在時也是 Cache-Control 的優先順序更高。

Cache-Control

Cache-Control 可以由多個欄位組合而成,主要有以下幾個取值:

  • max-age 指定一個時間的長度 時間單位是秒
  • no-cache 告訴瀏覽器,一定要回伺服器校驗,不管有沒有快取資料。 如果確定沒有被改,可以使用快取中的資料
  • no-store 告訴瀏覽器任何情況下都不要被快取。
  • public 僅體現在響應頭,通知瀏覽器可以無條件的快取該響應
  • private 僅體現在響應頭,通知瀏覽器只針對單個使用者快取響應. 且可以具體指定某個欄位.如private –“username”

協商快取

快取的資源到期了,並不意味著內容發生改變,如果伺服器的資源沒有差異,實際是上沒有必要再次請求,客戶端和伺服器端通過某種驗證機制驗證當前請求資源是否可以使用快取。

Last-modified/If-Modified-Since

Last-modified: 伺服器端資源的最後修改時間,響應頭部會帶上這個標識。第一次請求之後,瀏覽器記錄這個時間,再次請求時,請求頭部帶上 If-Modified-Since 即為之前記錄下的時間。伺服器端收到帶 If-Modified-Since 的請求後會去和資源的最後修改時間對比。若修改過就返回最新資源,狀態碼 200,若沒有修改過則返回 304。

注意:如果響應頭中有 Last-modified 而沒有 Expire 或 Cache-Control 時,瀏覽器會有自己的演算法來推算出一個時間快取該檔案多久,不同瀏覽器得出的時間不一樣,所以 Last-modified 要記得配合 Expires/Cache-Control 使用。

Etag/If-None-Match

由伺服器端上生成的一段 hash 字串,第一次請求時響應頭帶上 ETag: abcd,之後的請求中帶上 If-None-Match: abcd,伺服器檢查 ETag,返回 304 或 200。

關於 last-modified 和 Etag 區別,已經有很多人總結過了:

  • 某些伺服器不能精確得到資源的最後修改時間,這樣就無法通過最後修改時間判斷資源是否更新。
  • Last-modified 只能精確到秒。
  • 一些資源的最後修改時間改變了,但是內容沒改變,使用 Last-modified 看不出內容沒有改變。
  • Etag 的精度比 Last-modified 高,屬於強驗證,要求資源位元組級別的一致,優先順序高。如果伺服器端有提供 ETag 的話,必須先對 ETag 進行 Conditional Request。

注意:實際使用 ETag/Last-modified 要注意保持一致性,做負載均衡和反向代理的話可能會出現不一致的情況。計算 ETag 也是需要佔用資源的,如果修改不是過於頻繁,看自己的需求用 Cache-Control 是否可以滿足。

那麼最後就是頁面渲染了

瀏覽器拿到頁面後開始解析html程式碼 遇到js css img 等靜態資源時就像伺服器請求下載, 解析成對應的DOM樹 css 規則書 js指令碼通過DOM api和 css api來操作DOM樹

渲染 計算css樣式 (js可動態修改dom或者css進一步渲染樹和分佈) 構建渲染樹 確認佈局 繪製 而渲染玩比以後就是關閉TCp連線或繼續保持連線

通過四次揮手關閉連線

揮手完畢 頁面載入完畢 這就是頁面輸入url後整個過程

相關文章