譯文:瀏覽器輸入URL發生了什麼?

caihaihong發表於2019-02-24

翻譯:在瀏覽器導航欄輸入一個url後,發生了什麼?

作為一名軟體開發人員,關於網站應用的工作原理以及其中涉及到的技術:包括瀏覽器、HTTP、web server、請求處理等等,你一定有一個清晰的畫面。

過程
  1. 你在瀏覽器輸入一個url(www.baidu.com

image

  1. 瀏覽器對輸入的網站域名查詢相應的ip地址

image

導航欄的第一步工作是去獲取訪問域名所對應的ip地址,DNS的查詢過程如下:
  • 瀏覽器快取---瀏覽器會快取DNS域名解析記錄一段時間。有趣的是,作業系統不會告訴瀏覽器每一個NDS快取的存活時間,所以瀏覽器瀏覽器只會快取它們一小段固定時間(不同瀏覽器有所不同,一般是2-30分鐘)
  • OS作業系統快取---如果瀏覽器快取不存在想要的ip記錄,瀏覽器會通知作業系統(在window系統是通過gethostbyname)。作業系統有自己的一份快取。
  • 路由器快取---請求會繼續來到路由器,路由器有自己的快取記錄
  • ISP(Internet Servive Provider)網際網路服務商DNS快取---下一步查詢是ISP的DNS快取伺服器。
  • ISP DNS伺服器進行遞迴查詢---你的ISP的DNS伺服器開始了遞迴查詢,從根域名伺服器、通過頂級.com域名伺服器,到baidu的域名伺服器。很正常的,NDS伺服器有.com域名伺服器上的域名的快取,所以到根伺服器直接查詢沒有必要。

image

有一件讓人擔心的事情就是關於DNS域名解析,那就是像“baicu.com”這樣的完整的域名,好像只有單一的IP地址,幸運的是,這裡有些緩和瓶頸的方式。
  * 輪詢排程(Round-robin DNS)DNS是一種解決方案進行NDS域名解查詢返回多個IP地址,比只有ip地址好。舉個例子,facebook.com 實際上對映了4個IP地址。
  * 負載均衡(Load-balancer)是硬體上的用來監聽某個特定的ip地址,對轉發請求到另一臺伺服器。很多網站都會特別的使高效能的負載均衡器。
  * Geographic DNS(地理)通過獲取客戶端的地址位置,將域名對映到不同的IP地址,從而提高了可擴張性。
  這個對於呈現靜態資原始檔是很好的,這樣不同的伺服器不需要更新共享狀態。
  * 任播(Anycast)是一種路徑選擇技術,對於單一的IP地址對映到多個物理伺服器,很不幸,任播不適合TCP還有就是很少在在指令碼使用。
  
許多DNS伺服器自身是使用傳播是完成高效且低延遲的DNS查詢

複製程式碼
  1. 瀏覽器發了一個HTTP 請求到web伺服器

image

你能夠很確定facebook的主頁不會由瀏覽器快取提供,因為動態頁面的過期也是非常快的或者立即的(過期時間設定為過去) 所以瀏覽器會發以下這個請求到facebook伺服器

GET http://facebook.com/ HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, [...]
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; [...]
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Host: facebook.com
Cookie: datr=1265876274-[...]; locale=en_US; lsd=WW[...]; c_user=2101[...]
複製程式碼

Get請求去獲取‘htt p://facebook.com/’,瀏覽器對自己做了標識,對伺服器進行身份表明(user agent header)。還有宣告什麼型別的返回內容將會被接受(Accept and Accept-Encoding headers)。請求頭請求伺服器保持TCP連線的開啟以實現後續的請求。

這個請求也包含瀏覽器與該域名對應的cookies。或許你已經知道,cookies是跟蹤一個網站在不同的網頁請求的鍵值對。cookies儲存了登陸的使用者名稱,一個私密數字聯絡到使用者通過伺服器,一些使用者的設定等等。Cookies會被儲存在客戶端的某個檔案裡面,每個請求都會將cookies傳送到伺服器。

有很多種工具可以讓你看到原生的HTTP requests請求,還有對應的responses返回。用來檢視原生HTTP請求,我最喜歡的工具是fiddler,但是有很多其他的工具例如FireBug。這些工具都很好對於優化站點。

對於GETQ請求之外,另外一種型別的請求或許你很熟悉,那就是POST請求,典型的使用就是提交表單。一個get請求通過URL傳送它的請求引數(例如:htt p://robozzle.com/puzzle.aspx?id=85)。一個POST請求在請求體新增請求引數並且傳送,就是在請求頭下。

跟隨在URL"htt p://facebook.com/"的反斜槓是非常重要的,在這種情況,瀏覽器可以很安全的新增斜槓。對於“htt p://example.com/folderOrFile”這樣的URL形式,瀏覽器不能自動地新增反斜槓,因為它不確定這個“folderOrFile”是個目錄還是個檔案。對於這種情況,瀏覽器就會訪問這個網站不加反斜槓,那麼伺服器就會返回一個重定向,導致沒有必要的往返。

  1. FaceBoo 伺服器返回一個永久重定向

image

這是一個來自Facebook的伺服器的返回給瀏覽器請求的結果

HTTP/1.1 301 Moved Permanently
Cache-Control: private, no-store, no-cache, must-revalidate, post-check=0,
      pre-check=0
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Location: http://www.facebook.com/
P3P: CP="DSP LAW"
Pragma: no-cache
Set-Cookie: made_write_conn=deleted; expires=Thu, 12-Feb-2009 05:09:50 GMT;
      path=/; domain=.facebook.com; httponly
Content-Type: text/html; charset=utf-8
X-Cnection: close
Date: Fri, 12 Feb 2010 05:09:51 GMT
Content-Length: 0
複製程式碼

這個服務返回一個返回碼301告訴瀏覽器訪問“www.facebook.com/”而不是“http:/…

這裡有趣的內容為什麼伺服器堅持重定向,而不是立即返回使用者想要看到的頁面。 有一個理由就是關於搜尋引擎排名,看,如果有兩個不同的URL訪問同一個網頁,說http://www.igoro.com/ 還有 igoro.com/, 搜尋引擎會認為它們是兩個不同的網站,每個都是低收入連結和那麼低的排名嗎,搜尋引擎明白永久重定向(301),然後會結合兩個不同來源的傳入到同一個排名。 還有,相同的內容有多個URL對快取不是很友好。當有一部分內容有多個名字,他將會潛在存在多次在快取。

  1. 瀏覽器跟隨重定向

image

瀏覽器知道“htt p://www.facebook.com/”才是正確的地址,就進行了再次訪問請求

GET http://www.facebook.com/ HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, [...]
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; [...]
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Cookie: lsd=XW[...]; c_user=21[...]; x-referer=[...]
Host: www.facebook.com
複製程式碼

請求的頭部跟第一次是一樣的。

  1. 伺服器處理請求

伺服器將會收到一個get請求,對他進行處理,然後返回respones

這個看起來是一項直截了當的任務,但其實實際上這裡有很多有趣的工作發生。即使在 一個簡單的個人部落格網站,更別說在一個超大型的網站像Facebook。

  • Web服務軟體

Web服務軟體(Apache IIS)接受HTTP請求還有決定用什麼請求處理工具來處理本次請求,一個請求處理工具是一個專案(ASP,.NET,PHP,Ruby,...)讀取請求然後生成返回HTML。

在最簡單的情況,請求處理工具能夠被儲存在一個對映URLs結構的檔案層次結構。舉個例子 htt p://example.com/folder1/page1.aspx URL 將會對映到檔案/httpdocs/folder1/page1.aspx。web服務軟體也能夠被配置以至於URLs能夠手動對映到請求處理工具,所以對於page.aspx的公共URL能偶寫成:“ht tp://example.com/folder1/page1”

  • 請求處理工具

請求處理工具獲取HTTP請求,請求引數,cookies。它可能讀取請求還可能更新一些儲存在伺服器的資料。然後請求處理工具會生成返回一個HTML

有一個有趣的難題是每個動態網站遇到的關於如何儲存資料。小一點的網站經常會有一個單一的SQL資料庫去儲存資料,但是網站儲存一個巨大數量的資料或者有很多訪問者就不得不在多臺伺服器之間分離資料庫。解決方案主要有:分片sharding(基於主鍵在多個資料庫之間分離資料表),複製replication,還有使用弱化一致性語義的簡化資料庫。

延時一些處理進行批量處理是可以讓更新資料比較低效能消耗的技術。

  1. 服務返回一個HTML respones

image

這是服務生成發回的。

HTTP/1.1 200 OK
Cache-Control: private, no-store, no-cache, must-revalidate, post-check=0,
    pre-check=0
Expires: Sat, 01 Jan 2000 00:00:00 GMT
P3P: CP="DSP LAW"
Pragma: no-cache
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
X-Cnection: close
Transfer-Encoding: chunked
Date: Fri, 12 Feb 2010 09:05:55 GMT
複製程式碼

整一個返回結果是36kb,the bulk of them in the byte blob at the end that I trimmed.(怎麼翻譯?)

Content-Encoding頭告訴瀏覽器返回體是使用gaip演算法壓縮的。解壓檔案,你就可以看到期待的HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"   
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" 
      lang="en" id="facebook" class=" no_js">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-language" content="en" />
複製程式碼

除了壓縮方法,頭部也會指定怎麼樣去快取頁面,設的任何cookies,隱私資訊等等。

我們發現返回頭部設定Content-Type為text/html。頭部指導瀏覽渲染返回的結果內容是HTML,而不是說瞎子啊一個檔案。瀏覽器將會根據返回頭部決定怎麼樣去處理返回結果。但也會考慮其他因素,例如URL的擴充套件。

  1. 瀏覽器開始渲染HTML

image

即使在這之前瀏覽器已經接受過整個HTML文件,他也會開始渲染網站。

  1. 瀏覽器為嵌入在HTML的物件傳送請求

image

當瀏覽器開始渲染HTML,他會發現標籤裡面需要獲取其他URLs,瀏覽器將會傳送GET請求去獲取這些檔案

這裡有些URLs是我訪問facebook網站檢索的

Images
http://static.ak.fbcdn.net/rsrc.php/z12E0/hash/8q2anwu7.gif
http://static.ak.fbcdn.net/rsrc.php/zBS5C/hash/7hwy7at6.gif
…
CSS style sheets
http://static.ak.fbcdn.net/rsrc.php/z448Z/hash/2plh8s4n.css
http://static.ak.fbcdn.net/rsrc.php/zANE1/hash/cvtutcee.css
…
JavaScript files
http://static.ak.fbcdn.net/rsrc.php/zEMOA/hash/c8yzb6ub.js
http://static.ak.fbcdn.net/rsrc.php/z6R9L/hash/cq2lgbs8.js
複製程式碼

每一個URls都會經歷跟請求HTML相同的處理過程,所以,瀏覽器將會查詢DNS域名解析,傳送請求

然而,靜態檔案--不像動態頁面-允許瀏覽器快取它們。有些檔案或許是快取提供的一點也沒有聯絡伺服器。瀏覽器知道對某個特定的檔案快取多長時間是因為返回的檔案包括一個過期的頭部。另外,每個返回也包含一個ETag頭部像一個版本號---如果瀏覽器發現已經有一個跟ETag版本相同的檔案,就會馬上停止傳輸。

  1. 瀏覽器傳送進一步的非同步(Ajax)請求

image

Web2.0的精髓就是客戶端頁面可以繼續跟客戶端互動即使在網已經請求渲染。

例如,Facebook 聊天將會繼續更新你的新登入的或者退出的使用者列表。在你的瀏覽器Js已經被執行傳送非同步請求。非同步請求是程式設計式指導GET或者POST請求到特定的URL.在Facebook這個例子,客戶端傳送一個post請求htt p://www.facebook.com/ajax/chat/buddy_list.php 去獲取的你的線上好友列表。

這個模式有時候被聯絡到AJAX,代表“Asynchronous JavaScript And XML”,但是沒有特定的理由說為什麼伺服器需要格式化返回結果為XML。

相關文章