從輸入url到頁面顯示內容的過程發生了什麼

2021-10-24 01:36:45 字數 3868 閱讀 5045

瀏覽器通過輸入的url來解析要請求的是什麼協議,構建請求報文,這裡要構建的就是http請求報文。

http請求報文包括報文首部和報文主體,對請求報文來說,報文首部包括請求行各種首部字段;而對響應報文來說,報文首部包括狀態行各種首部字段

請求行:get/http/1.1 (請求方法和相應的協議)

狀態行:http/1.1 200 ok (相應的協議和狀態碼)

各種首部字段:比如cache-control和expires,還有if-no-match,if-modified-since,etag等

報文主體:在get請求中沒有,post請求中向伺服器發出的資料,響應報文中為伺服器返回給客戶端的內容

(在這部分設定一些相關的字段會影響後面的強快取和協商快取)

通過請求報文,找到本地相應資源的響應報文,檢視expires或cache-control來判斷是否使用強快取,在http1.0裡面expires優先於cache-control,而在http1.1則相反。

如果快取資源還沒有過期,那麼就使用本地快取的資源,返回狀態碼304,如果資源已過期,那麼接著執行。

(這裡可以從expires和cache-control來表明http1.1比http1.0多了什麼)

強快取是根據返回頭中的expires或者cache-control兩個欄位來控制的,都是表示資源的快取有效時間。

expires是 http 1.0 的規範,值是乙個gmt 格式的時間點字串,比如 expires:mon,18 oct 2066 23:59:59 gmt 。這個時間點代表資源失效的時間,如果當前的時間戳在這個時間之前,則判定命中快取。有乙個缺點是,失效時間是乙個絕對時間,如果伺服器時間與客戶端時間偏差較大時,就會導致快取混亂。而伺服器的時間跟使用者的實際時間是不一樣是很正常的,所以 expires 在實際使用中會帶來一些麻煩。

cache-control這個欄位是 http 1.1 的規範,一般常用該字段的 max-age 值來進行判斷,它是乙個相對時間,比如

.cache-control:max-age=3600 代表資源的有效期是 3600 秒。並且返回頭中的 date 表示訊息傳送的時間,表示當前資源在 date ~ date +3600s 這段時間裡都是有效的。不過我在實際使用中常常遇到設定了 max-age 之後,在 max-age 時間內重新訪問資源卻會返回 304 not modified ,這是由於伺服器的時間與本地的時間不同造成的。當然 cache-control 還有其他幾個值可以設定, 不過相對來說都很少用了:

no-cache 不使用本地快取。需要使用協商快取。

no-store直接禁止瀏覽器快取資料,每次請求資源都會向伺服器要完整的資源, 類似於 network 中的 disabled cache。

public 可以被所有使用者快取,包括終端使用者和 cdn 等中介軟體**伺服器。

private 只能被終端使用者的瀏覽器快取。

如果 cache-control與 expires 同時存在的話, cache-control 的優先順序高於 expires。

我們請求的時候,請求的位址是ip位址,所以要將我們寫的url位址轉換為ip位址,就需要dns解析。在解析的時候,首先檢視本地dns伺服器是否有相應網域名稱對應的ip位址,如果有的話,直接返回請求該ip位址。

如果沒有的話,根據該位址向根網域名稱伺服器發起請求,獲取對應的頂級網域名稱伺服器的位址,向該頂級網域名稱伺服器發起請求,獲得對應的許可權網域名稱伺服器對應的位址,然後返回最終的ip位址。

返回的時候,不僅會返回到要請求的地方,還將該位址快取到本地dns伺服器。

首先,我們要進行三次握手建立tcp連線。首先最開始客戶端和服務端的tcp程序都處於closed(關閉)狀態,由客戶端主動開啟連線,服務端被動開啟連線。

在tcp連線建立好之後,就可以從瀏覽器向服務端傳送http請求報文了。準備好http請求報文後,就向伺服器發起http請求,然後等待伺服器返回響應報文。

在發起http請求後,我們所獲取的資源還不一定是最新的資源,要先通過協商快取來判斷是否使用快取

通過在請求中新增if-modified-since欄位和if-none-match欄位來向伺服器確認當前資源是否繼續使用快取

協商快取是由伺服器來確定快取資源是否可用。 主要涉及到兩對屬性字段,都是成對出現的,即第一次請求的響應頭帶上某個字, last-modified 或者 etag,則後續請求則會帶上對應的請求字段 if-modified-since或者 if-none-match,若響應頭沒有 last-modified 或者 etag 字段,則請求頭也不會有對應的字段。

last-modified/if-modified-since 二者的值都是gmt格式的時間字串, last-modified 標記最後檔案修改時間, 下一次請求時,請求頭中會帶上 if-modified-since 值就是 last-modified 告訴伺服器我本地快取的檔案最後修改的時間,在伺服器上根據檔案的最後修改時間判斷資源是否有變化, 如果檔案沒有變更則返回 304 not modified ,請求不會返回資源內容,瀏覽器直接使用本地快取。當伺服器返回 304 not modified 的響應時,response header 中不會再新增的 last-modified 去試圖更新本地快取的 last-modified, 因為既然資源沒有變化,那麼 last-modified 也就不會改變;如果資源有變化,就正常返回返回資源內容,新的 last-modified 會在 response header 返回,並在下次請求之前更新本地快取的 last-modified,下次請求時,if-modified-since會啟用更新後的 last-modified。

etag/if-none-match,值都是由伺服器為每乙個資源生成的唯一標識串,只要資源有變化就這個值就會改變。伺服器根據檔案本身算出乙個雜湊值並通過 etag欄位返回給瀏覽器,接收到 if-none-match 字段以後,伺服器通過比較兩者是否一致來判定檔案內容是否被改變。與 last-modified 不一樣的是,當伺服器返回 304 not modified 的響應時,由於在伺服器上etag 重新計算過,response header中還會把這個 etag 返回,即使這個 etag 跟之前的沒有變化。

通過強快取,協商快取,最後不管是在快取,還是在一些快取的伺服器上,又或者是在源伺服器上,我們最終拿到了響應資源,將其渲染到頁面上。

請求實際上就返回了這樣的html文字 如果是在http2.0中,因為有服務端推送的功能,所以可能當我們去請求乙個html的時候,會將這個html引用到的css檔案和js檔案都通過服務端推送到客戶端,這樣請求的次數也會減少

(如果問的時候沒說具體請求什麼,這裡可以扯一下如果是只請求資源的部分內容的話,可以通過在請求頭新增range來選擇要請求哪一部分,順便扯一下http1.1裡新的狀態碼206)

此外,我們在這裡獲取到響應報文,還可能得到乙個301或302狀態碼的響應報文。這時網路程序會從響應頭的location欄位裡面讀取重定向的位址,然後再發起新的http或者https請求,一切又重頭開始了

(這裡可以盡情扯永久重定向和臨時重定向的區別,這裡我就不扯了)

這裡實際上也可以提一下跨域,上一次我面試的時候被問到請求到顯示的時候,說了句用img的src屬性去得到一張不會引起跨域,後來就問了句你剛才說了跨域,說說跨域吧(引導成功.jpg)

(關於跨域的內容包括解決辦法可以又寫出一篇文章。。。我這裡就不扯過多了)

因為我們請求的是乙個html檔案,而實際上,瀏覽器無法直接理解和使用html,所以需要將其解析為瀏覽器能理解的解構---dom樹,我們可以試著將下面的這部分html內容來轉換成dom樹試試。

從輸入url到頁面顯示

瀏覽器首先從瀏覽器快取,本地快取,本地的hosts檔案查詢對應的ip 如果在本地沒找到,接下來會傳送乙個dns請求到本地dns伺服器,本地dns查詢它的快取記錄 如果沒有,本地伺服器向dns根伺服器查詢 根伺服器並沒有記錄具體的網域名稱和ip位址的對應關係,而是告訴本地dns 伺服器,你可以到域伺服...

請描述從輸入乙個url到頁面顯示的整個過程?

輸入 url 瀏覽器與伺服器 通過tcp三次握手協商來建立乙個 tcp連線。1.瀏覽器問 伺服器,在嗎?2.伺服器回答 在的,怎麼了?3.瀏覽器說 我想請你幫個忙 瀏覽器伺服器 傳送乙個 http 請求報文 伺服器處理請求並返回乙個 http 響應報文 瀏覽器收到響應,進行客戶端渲染,生成dom樹 ...

從輸入URL到頁面展示

這個時候有兩種情況,第一種是子網域名稱伺服器返回了這個url對應的ip位址,第二種情況是經過了cdn排程,如果目標 使用了cdn服務,則需要在cdn服務商的平台設定相應的cname記錄,這個記錄是cdn服務廠商的乙個dns伺服器的網域名稱,子網域名稱伺服器會返回這個cname記錄,本地dns伺服器得...