從開始到結束,當你在瀏覽器中輸入URL時會發生什麼事情

本文描述了瀏覽器如何使用HTTP/1.1協議進行頁面請求

如果你曾經參加過面試,可能會被問到:“當你在Google搜索框中輸入內容並按下Enter鍵時會發生什麼”.

這是一個最常問的問題之一。人們只是想看看你是否能解釋一些相當基本的概念,以及你是否對互聯網的工作原理有任何了解。

在這篇文章中,我將分析當你在瀏覽器的地址欄中輸入URL並按下Enter鍵時會發生什麼。

這是一個非常有趣的主題,我可以在單獨的文章中深入探討其中的許多技術。

這項技術很少更改,並且為人類所建造的最複雜和最廣泛的生態系統之一提供動力。

HTTP協議

首先,我特別提到HTTPS,因為使用HTTPS連接的情況有所不同。

我僅分析URL請求

現代瀏覽器具有知道你在地址欄中輸入的是實際URL還是搜索詞的能力,如果不是有效的URL,它們將使用默認搜索引擎。

我假設你輸入的是實際URL。

當你輸入URL並按下Enter鍵時,瀏覽器首先構建完整的URL。

如果你只輸入了一個域名,例如flaviocopes.com,瀏覽器默認會在前面添加 HTTP://,使用預設的HTTP協議。

與macOS / Linux相關的事情

只是提一下。Windows可能會略有不同。

DNS查找階段

瀏覽器開始進行DNS查找以獲取服務器的IP地址。

域名對於我們人類來說很方便,但互聯網根據IP地址對服務器的精確位置進行組織,IP地址是一組類似 222.324.3.1(IPv4)的數字。

首先,它檢查DNS本地緩存,看看域名最近是否已被解析。

Chrome有一個方便的DNS緩存可視化工具,你可以在chrome://net-internals/#dns查看。

如果在那裡找不到任何內容,瀏覽器將使用DNS解析器,使用gethostbyname POSIX系統調用檢索主機信息。

gethostbyname

gethostbyname首先在本地主機文件中查找,該文件在macOS或Linux中位於/etc/hosts,以查看系統是否在本地提供該信息。

如果這沒有提供有關該域的任何信息,系統將向DNS服務器發送請求。

DNS服務器的地址存儲在系統首選項中。

下面是兩個常用的DNS服務器:

  • 8.8.8.8:Google公共DNS服務器
  • 1.1.1.1:CloudFlare DNS服務器

大多數人使用由其網絡提供商提供的DNS服務器。

瀏覽器使用UDP協議執行DNS請求。

TCP和UDP是計算機網絡的兩個基礎協議。它們處於相同的概念層級,但TCP是面向連接的協議,而UDP是無連接的協議,更加輕量級,用於以較小開銷發送消息。

如何進行UDP請求不在本教程的範圍內

DNS服務器可能在緩存中有域的IP。如果沒有,它將向樹狀DNS服務器發送請求。這是一個由13台實際服務器(分佈在全球各地)組成的系統,該系統驅動整個互聯網。

DNS服務器不知道地球上每個域名的地址。它只知道頂級DNS解析器的位置。頂級域是域名的擴展名:.com.it.pizza等。

一旦根DNS服務器收到請求,它會將請求轉發給頂級域(TLD)DNS服務器。假設你正在尋找flaviocopes.com,根域DNS服務器會返回.com TLD服務器的IP。

現在我們的DNS解析器將緩存該TLD服務器的IP,所以它不需要再次向根DNS服務器請求。

TLD DNS服務器將具有我們正在查找的域的權威名稱服務器的IP地址。

如何做到的?當你購買一個域名時,域名註冊商會向相應的TDL發送名稱服務器。當你更新名稱服務器(例如,當你更換主機提供商時),你的域名註冊商將自動更新此信息。

這些是主機提供商的DNS服務器。通常有不止1個,以作為備份。

例如:

  • ns1.dreamhost.com
  • ns2.dreamhost.com
  • ns3.dreamhost.com

DNS解析器從第一個開始,並嘗試查詢你正在查找的域名(包括子域名)的IP。

這是IP地址的終極真相來源。

現在我們有了IP地址,可以繼續我們的旅程。

TCP請求握手

有了服務器的IP地址後,瀏覽器現在可以與服務器建立TCP連接。

在開始發送數據之前,TCP連接需要進行一些握手。

建立連接後,我們可以發送請求。

發送請求

請求是一個根據通信協議結構化的純文本文檔。

它由3部分組成:

  • 請求行
  • 請求標頭
  • 請求主體

請求行

請求行在一行上設定以下內容:

  • HTTP方法
  • 資源位置
  • 協議版本

示例:

GET / HTTP/1.1

請求標頭

請求標頭是一組field: value對,用於設定某些值。

其中有2個強制性的字段,其中之一是Host,另一個是Connection,而其他所有字段都是可選的:

Host: flaviocopes.com
Connection: close

Host指示我們要定位的域名,而Connection始終設置為close,除非必須保持連接。

一些最常用的標頭字段有:

  • Origin
  • Accept
  • Accept-Encoding
  • Cookie
  • Cache-Control
  • Dnt

還有許多其他標頭字段。

標頭部分以空行結束。

請求主體

請求主體是可選的,在GET請求中不使用,在POST請求中非常常用,有時在其他動詞中也使用,它可以包含以JSON格式的數據。

由於我們現在正在分析GET請求,因此主體是空的,我們不會再深入研究。

響應

一旦請求被發送,服務器會處理它並發送回響應。

響應以狀態碼和狀態消息開始。如果請求成功並返回200,它將以以下方式開始:

200 OK

請求可能返回不同的狀態碼和消息,例如:

404 Not Found
403 Forbidden
301 Moved Permanently
500 Internal Server Error
304 Not Modified
401 Unauthorized

然後,響應包含一個HTTP標頭列表和響應主體(由於我們在瀏覽器中進行請求,響應主體將是HTML)。

解析HTML

瀏覽器現在已經收到HTML並開始解析它,並且將為頁面所需的所有資源重複執行完全相同的過程:

  • CSS文件
  • 圖片
  • 網站標誌
  • JavaScript文件

瀏覽器如何呈現頁面超出了本範圍,但重要的是理解我描述的過程不僅適用於HTML頁面,而且適用於通過HTTP傳遞的任何項目。