1. 程式人生 > >From URL to Interactive(一)---伺服器到客戶端

From URL to Interactive(一)---伺服器到客戶端

最近想比較系統的關注一下國外的技術部落格。順帶將一些文章翻譯下。

這是《From URL to Interactive》的三篇系列文章的第一篇《Server to Client》。《From URL to Interactive》是個引子就不譯了。有興趣可以看原文:https://alistapart.com/article/from-url-to-interactive。文章比較簡潔易懂。其實不翻譯也能看懂。就是閒的沒事,翻譯下

-----------------------------------------------------------------------------------------------------------------------------

在瀏覽器開始行動之前,它必須首先知道要去哪裡。有多種方法可以到達某個地地址:在位址列中輸入一個URL,在頁面上點選一個連結或者點選其他應用程式中的連結,或單擊收藏夾中的收藏。無論如何,這些都會導致所謂的導航。導航是任何Web互動的第一步,因為它啟動了一個有連鎖反應的事件,事件最終使得網頁被載入到瀏覽器中。

發起請求

一旦將URL提供給瀏覽器來載入,就會發生一些事情

檢查是否需要HSTS升級

首先,瀏覽器需要確定URL是否指定為HTTP(非安全)方案(譯者:瀏覽器支援其他協議,如FTP,或者直接file開頭的)。如果是HTTP請求,瀏覽器需要檢查域名是否在HSTS列表中(HTTP安全性傳輸協議)。該列表包括預載入的域名列表和先前使用HSTS訪問過的域名的列表, 兩者都儲存在瀏覽器中。如果請求的HTTP主機位於HSTS列表中,則會用HTTPS協議代替HTTP協議。這就是為什麼你會發現,即使你試圖在現代瀏覽器中鍵入http://www.bing.com,它也會將你傳送到https://www.bing.com。

檢查Service Workers

接下來,瀏覽器需要確定 service worker 是否可以處理請求 - 這在使用者離線且沒有網路連線的情況下尤為重要。Service Worker是瀏覽器中相對較新的功能。它們通過允許攔截網路請求(包括頂級請求)來啟用具有離線功能的網站,以便可以從指令碼控制的快取中提供響應。

訪問頁面時可以註冊service worker,這裡有一個記錄了service worker註冊和URL對映到本地資料庫的過程。確定是否安裝了service worker就像在該資料庫中查詢導航的URL一樣簡單。如果該給定URL存在service worker,則允許它處理對該請求的響應。如果瀏覽器中的“導航預載入”功能在可用,並且站點可以使用它,則瀏覽器將同時向網路詢問初始導航請求。這是有益的,因為它允許瀏覽器不阻止潛在的但較慢的service worker的啟動。

在沒有service wokrer處理初始請求(或者正在使用導航預載入)的情況下,瀏覽器將繼續詢問網路層。

檢查網路快取

瀏覽器通過網路層檢查其快取中是否有較新的響應。這通常由Cache-Control響應中的標記定義,其中設定a max-age表示快取專案可以被快取多久,即快取結果被視為最新的結果的最長時間,設定no-store則表示是否應該快取響應。當然,如果瀏覽器在其網路快取中找不到任何內容,則需要網路請求。如果快取中有fresh的響應,則會將其返回以便載入頁面。如果找到了資源但它不是fresh的,瀏覽器可能會轉向下一步,將請求轉換為有條件的revalidation請求,revalidation請求包含一個If-Modified-Since或If-None-Match標題告訴伺服器瀏覽器中快取內容的版本。伺服器可以通過返回HTTP 304 (Not Modified)且沒有body內容來告訴瀏覽器其副本仍然是最新的,或者通過返回攜帶新版本的資源的HTTP 200 (OK)響應來告訴瀏覽器其副本是陳舊的(譯者:這裡同時將最新的請求響應返回回來了)。

檢查連線(connection)

如果先前與被請求的主機和埠建立了連線,則將重用連線而不是建立新連線。如果沒有,瀏覽器會詢問網路層以瞭解它是否需要進行DNS(域名系統)查詢。這將涉及檢視本地DNS快取(儲存在您的裝置上),並且,根據該快取的fresh程度,決定是否查詢遠端DNS(它們可以由Internet服務提供商託管),這最終會使得獲取到正確的IP地址供瀏覽器連線。

在某些情況下,瀏覽器可能能夠預測將訪問哪些域,並且可以提前與這些域建立連線。該頁面可以通過使用resource hints(如rel="preconnect”連結標記)向瀏覽器提示。使用resource hint有用的一種情況是,如果使用者在Bing搜尋結果頁面上,並且預期最初幾個搜尋結果最有可能被訪問。在這種情況下,提前啟動與這些域名的連線可以幫助您在以後單擊這些連結時不必支付DNS查詢和連線設定的成本。

建立聯絡(Establish Connection)

現在,瀏覽器可以與伺服器建立連線了,以便讓伺服器知道它將同時與客戶端進行收發資料。如果我們使用了 TLS,我們還需要執行TLS握手協議來驗證伺服器提供的證書。

傳送請求到伺服器

通過該連線的第一個請求是最上層的頁面請求。通常,這將是一個server提供的HTML檔案,會由伺服器返回給客戶端。

處理Response

當資料流傳輸到客戶端後,瀏覽器將分析response資料。首先,瀏覽器檢查響應的頭資訊(header)。HTTP頭是作為HTTP響應的一部分發送的name-value對。如果響應的header指示重定向(例如,通過Location欄位),則瀏覽器將重新開始導航過程並退回到“檢查是否需要HSTS升級”的第一步。

如果伺服器response被壓縮(compressed )或有分塊(chunked),瀏覽器將嘗試解壓縮和拼裝它。

在讀取響應的同時,瀏覽器也開始並行地將response寫入網路快取。

接下來,瀏覽器將嘗試瞭解傳送到瀏覽器的檔案的MIME型別,因此它可以適當地解釋如何載入檔案。例如,影象檔案將作為影象載入,而HTML檔案則將被解析和渲染呈現。如果要使用HTML解析器來處理這個檔案,瀏覽器則會同時掃描response的內容以查詢可能要下載的資源的URL,以便瀏覽器可以在頁面開始渲染之前提前開始這些下載。本系列的下一篇文章將對此進行更詳細的介紹。

到目前為止,所請求的URL已經記錄到瀏覽器歷史記錄中,這使得它可以在瀏覽器的後退和前進功能中進行導航的原因。

這是一個流程圖,它概述了到目前為止所討論的內容,並提供了更多細節:

如您所知,頁面將繼續發出請求,因為頁面上有許多子資源對整體體驗很重要,包括影象,JavaScript和樣式表。另外,還有那些被子資源所引用的資源,如啟動背景圖片(CSS中引用的)或其他資源fetch(),import()或AJAX呼叫也需要被請求。沒有這些,我們只會有一個沒有太多互動性的普通頁面。正如您在前面的解釋和流程圖中看到的那樣,請求的每個資源都部分受到瀏覽器快取策略的影響。

快取記憶體

如前所述,瀏覽器管理著一個網路快取,允許在許多情況下重用先前下載的資源。這對於大部分不變的資源特別有用,例如來自框架的logos和JavaScript。儘可能利用此快取非常重要,因為它可以通過重用本地快取的資源來減少網路請求的數量。反過來,這有助於最大限度地減少所需的其他費力且潛在的操作,從而縮短頁面載入時間。

當然,網路快取的配額會影響快取的專案數量以及快取時間。這並不意味著網站在此事上沒有發言權。response中的Cache-Control頭資訊用來控制瀏覽器的快取邏輯。在某些情況下,告訴瀏覽器不要快取任何東西(例如with Cache-Control: no-store),因為預估到response會每次都不同。在其他情況下,讓瀏覽器無限期地快取內容是有意義的(Cache-Control: immutable),因為給定URL的response永遠不會改變,在這種情況下,使用不同的URL指向同一資源的不同版本而不是讓同一個URL的資源進行版本的變動,因為始終會使用快取的版本。

當然,網路快取不是瀏覽器中唯一的快取型別。可以通過JavaScript利用程式化快取。具體地,在上面給出的service worker的示例中,service worker可以攔截頂級頁面的初始資源請求,然後可以使用其程式快取的由站點定義的快取內容。這很有用,因為它使網站能夠更好地控制何時使用快取項。這些快取是origin-bound的(譯者:下面Origin model 詳細介紹),這意味著每個域名空間都有自己的沙盒快取集,用它可以控制實現域名之間的快取隔離。

原點模型(Origin model)

原點只是一個由方案/協議、主機名和埠組成的三元組。例如,https://www.bing.com:443具有HTTPS協議、www.bing.com主機名和443作為埠。如果與其他來源相比,其中有任何一個元素不同,則認為它們是不同的來源。例如,https://images.bing.com:443和http://www.bing.com:80是不同的來源。

原點是瀏覽器的一個重要概念,因為它定義了資料如何沙箱化和安全化。在大多數情況下,出於安全目的,瀏覽器強制執行同源策略(same-origin policy),這意味著一個源無法訪問另一個源的資料 - 兩者都需要是同一個源。具體來說,在前面介紹的快取案例中,https://images.bing.com:443和http://www.bing.com:80都無法看到另一個的程式快取。

如果bing.com想要載入來自microsoft.com的JavaScript檔案,它將發出一個跨源資源請求(cross-origin resource request ),瀏覽器將在該請求上強制實施同源策略。為了允許這種行為,microsoft.com需要通過指定CORS(Cross-Origin Resource Sharing)header資訊與bing.com合作,使得bing.com能夠從microsoft.com載入JavaScript檔案。設定正確的CORS header資訊是一種很好的做法,藉此瀏覽器可以適當地處理跨源資源請求。

結論

現在您已經瞭解了我們如何從伺服器訪問到客戶端 - 以及介於兩者之間的所有細節 - 請繼續關注以瞭解載入網頁的下一步:我們如何從HTML tags轉到DOM。

關於作者

Ali Alabbas

Ali Alabbas是Microsoft Edge網路平臺團隊的PM,他負責其中的service workersbrowser storage networking。同時他也是W3C的撰稿人和索引資料庫(Indexed Database)規範的編輯。