深入淺出經典面試題:從瀏覽器中輸入URL到頁面載入發生了什麼 - Part 1
背景
“從瀏覽器中輸入URL到頁面載入的發生了什麼“,這是一道經典的面試題,涉及到的知識面非常多,但作為一個自認為對網路知識掌握的比較好的老碼農來說,回答這個問題自然不在話下。如果這道題目如果在面試出現,對我來說就是送分題啊。儘管如此,我還是願意花一些時間根據我自己的理解回答一下這個題目,看我自己到底掌握的有多深,同時也把自己的知識梳理一下。
這讓我想起另外一件往事,這道題有點類似於“在手機上瀏覽器上輸入一個URL,手機做了一些什麼”,我當時學習通訊裡的核心網時就給自己提出過這個問題。
我非常願意將這個面試題的答案共享出來,一是希望得到大家的意見,二是也希望對那些不是特別熟的人起到一些幫助。
因為文章較長,我將它們分為三大部份,後面會提供該文章的完整PDF版本,供大家下載。
從本文裡學到什麼?
正如前面所說,這篇文章涉及到的知識面非常豐富,我相信您絕對可以從本文裡學到很多基礎知識,還有一些高階話題。
- DNS的解析原理,常用命令,埠等
- TCP/IP模型,三次握手,四次揮手。
- HTTP/HTTPS的原理和解析。
- 瀏覽器render一個頁面
- Web安全性問題
- 抓包,分析TCP模型,三次握手,SSL/TLS,讓學起來不再枯燥。
- 其他一些高階話題。
自認為是目前寫的最詳細的一篇文章了,因為裡面有理論,有實戰,應該會起到一個比較好的效果。
總概: 幾大步驟
總的來說,當你輸入在瀏覽器裡輸入一個URL到頁面載入,發生的順序如下:
- DNS查詢
- TCP連線
- 傳送HTTP請求
- Server處理HTTP請求並返回HTTP報文
- 瀏覽器解析並render頁面
- HTTP連線斷開
後面將對以上步驟詳細介紹。
DNS查詢
DNS解析流程
假設輸入的URL是包含域名的,那肯定會涉及到DNS解析。當然,如果URL僅僅是IP,那就不會涉及到DNS的。域名的出現是為了方便記憶,因為域名比IP好記。我們這裡假設URL包含域名。
解析的步驟大致如下圖:
首先,在 本地域名伺服器 中根據域名查詢IP地址,如果沒有找到的情況下,本地域名伺服器會向 根域名伺服器 傳送一個請求。
如果根域名伺服器也不存在該域名時,本地域名會向com 頂級域名服務 器(TLD)傳送一個請求,依次類推下去。
直到最後本地域名伺服器得到google的IP地址並把它快取到本地,供下次查詢使用。
可以參考頁面 ofollow,noindex" target="_blank">https://www.verisign.com/en_US/website-presence/online/how-dns-works/index.xhtml ,該頁面詮釋了DNS的過程。
需要說明的是Root DNS Server一般有13個,後面有個點(.),別忘了。
a.root-servers.net.
c.root-servers.net.
j.root-servers.net.
b.root-servers.net.
i.root-servers.net.
d.root-servers.net.
k.root-servers.net.
f.root-servers.net.
l.root-servers.net.
h.root-servers.net.
m.root-servers.net.
g.root-servers.net.
e.root-servers.net.
DNS的優化
我們發現,一個DNS查詢在沒有快取的情況下會有6步,這將是一個耗時的過程,如果DNS 查詢時間過長,甚至會影響到使用者體驗。
那麼現階段是怎麼優化的呢?快取。DNS是存在著多級快取,從離瀏覽器的距離排序的話,有以下幾種: 瀏覽器快取,系統快取,路由器快取,IPS伺服器快取,根域名伺服器快取,頂級域名伺服器快取,主域名伺服器快取。
我們以Chrome為例子,輸入 chrome://net-internals/#dns ,我們會看到如下介面:

這裡的Capacity: 1000,代表快取1K條,那麼每條記錄快取多久呢?參看
timeout 1
這裡的1代表1分鐘。
如果是系統快取,一般分2種情況:
Linux 作業系統
見下圖,一般在/etc/hosts下。
Windows作業系統
一般在C:\Windows\System32\Drivers\etc\hosts。
談到這裡,我給大家分享一個特別有用的技巧。
我們在做開發和測試時,會有一種情況,經常會去訪問某個(測試)URL,例如 http://192.168.1.8:8080/admin/login , 如果這樣的話,我們極有可能存在一個問題,覺得每次輸入ip真的很麻煩。怎麼解決?那麼我們可以這麼做,利用DNS的原理,將某個偽hostname(abc-test)加入到hosts裡,只需加入一條記錄:
192.168.1.8. abc-test
這樣就可以用 http://abc-test:8080/admin/login 去訪問了,簡單易用,對吧。
DNS負載均衡
不知道大家有沒有注意或思考過一個問題,Google在全球都有伺服器,不同的國家或區域訪Google,是不是都很快,這就是Google GSLB的作用。也就是說不同的區域訪問Google返回的IP是不一樣的,甚至在同一個辦公室訪問Google,返回回來的IP也有可能是不一樣的。
為什麼呢?這裡用的就是DNS負載均衡,不然Google怎麼去支援全球幾十億客戶的請求呢。總之,DNS會根據你的位置或IP返回一個合適的IP給你用。除了Google,一些CDN的SP例如Akamai、AWS、Azure、阿里雲都有類似的服務。
DNS Record(記錄)
DNS記錄是一個非常重好的概念。DNS記錄型別如下表。
記錄型別 |
含義簡介 |
A(Address) |
指定域名對應的IPv4地址 |
AAAA |
指定域名對應的IPv6地址 |
NS(Name Server) |
指定該域名由哪個DNS伺服器來進行解析 |
MX(Mail Exchanger) |
郵件交換記錄,用於電子郵件系統發郵件時根據收信人的地址字尾來定位郵件伺服器 |
CNAME |
別名記錄,多個域名對映到同一臺計算機(如同一主機提供mail和www服務) |
TXT |
主機名或域名的說明 |
TTL(Time-To-Live) |
DNS伺服器中儲存的時間 |
PTR |
將一個主機地址對映到對應的域名 |
HINFO |
說明對映到特定 DNS 主機名的 CPU 型別和作業系統型別 |
在這裡只介紹常用的A Record, CNAME,MX,NS。
A記錄
A記錄是用的最多的一種型別。
A (Address) 記錄是用來指定主機名(或域名)對應的IP地址記錄。使用者可以將該域名下的網站伺服器指向到自己的Web Server上。
同時也可以設定該域名的子域名。通俗來說A記錄就是伺服器的IP,域名繫結A記錄就是告訴DNS,當你輸入域名的時候給你引導向設定在DNS的A記錄所對應的伺服器。
後面的抓包分析會對A記錄進行分析,讓您有直觀認識。
CNAME記錄
CNAME記錄是另一種用的比較多的記錄,可以將一個域名或者子域名指向另外一個主機名。
最常用的使用場景是什麼呢?沒錯,CDN就是這種方式。舉個例子,例如公司A想把自己的圖片放在Akamai的CDN上,A的子域名是img.abc.com, 而 Akamai的CDN服務域名是img.akaimacdn.com. 但是A公司期望用自己的域名嗎,而不是Akamai的域名。為了實現這個目標,怎麼辦?是的,使用CNAME,只需要將子域名img.abc.com指向到img.akaimacdn.com。問題又來了,在哪裡設定呢?肯定是在公司A這邊的DNS server上,而不是Akamai那邊。
後面的抓包分析會對MX進行分析,讓您有直觀認識。
MX記錄
MX(Mail Exchanger)記錄,字面意思很直觀,知道它用來做郵件路由,使用者可以將域名下的郵件伺服器指向到自己的郵件伺服器上,然後可以自己操控所有的郵箱設定。所以只需線上填寫伺服器的IP地址,即可以將域名下的郵件全部轉到您自己設定相應的郵件伺服器上。
NS記錄
NS記錄用來解析伺服器記錄,表明由哪臺伺服器對該域名進行解析,這裡的NS記錄只對子域名生效。
例如使用者希望由12.34.56.78這臺伺服器解析sub1.mydomain.com,則需要設定 sub1.mydomain.com的NS記錄。
這裡涉及到一個問題,細心的我們會發現A記錄也有該功能,這裡就涉及到優先順序的問題了。NS記錄優先於A記錄。如果一個主機地址同時存在NS記錄和A記錄,則A記錄不生效。
DNS常用命令和工具
只介紹2個常用的命令dig和nslookup。
dig
dig是一個DNS查詢工具。
[warren]$ dig
; <<>> DiG 9.9.5-3ubuntu0.16-Ubuntu <<>>
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57775
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;. IN NS
;; ANSWER SECTION:
. 16265 IN NS a.root-servers.net.
. 16265 IN NS c.root-servers.net.
. 16265 IN NS j.root-servers.net.
. 16265 IN NS b.root-servers.net.
. 16265 IN NS i.root-servers.net.
. 16265 IN NS d.root-servers.net.
. 16265 IN NS k.root-servers.net.
. 16265 IN NS f.root-servers.net.
. 16265 IN NS l.root-servers.net.
. 16265 IN NS h.root-servers.net.
. 16265 IN NS m.root-servers.net.
. 16265 IN NS g.root-servers.net.
. 16265 IN NS e.root-servers.net.
;; Query time: 0 msec
;; SERVER: 208.113.157.202#53(208.113.157.202)
;; WHEN: Thu Nov 29 18:04:06 PST 2018
;; MSG SIZE rcvd: 239
再看看dig 京東的域名 www.jd.com 會有什麼效果。
dig www.jd.com
; <<>> DiG 9.10.6 <<>> www.jd.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2675
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;www.jd.com. IN A
;; ANSWER SECTION:
www.jd.com. 300 IN CNAME www.jd.com.gslb.qianxun.com.
www.jd.com.gslb.qianxun.com. 300 IN CNAME www.jdcdn.com.
www.jdcdn.com. 300 IN A 61.174.55.1
;; Query time: 3 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Fri Nov 30 10:07:37 CST 2018
;; MSG SIZE rcvd: 106
紅色部分為有CNAME記錄和A記錄。
nslookup
nslookup適用於Windows,Linux,macOS等作業系統。
nslookup www.jd.com
Server: 192.168.1.1
Address: 192.168.1.1#53
Non-authoritative answer:
www.jd.com canonical name = www.jd.com.gslb.qianxun.com.
www.jd.com.gslb.qianxun.com canonical name = www.jdcdn.com.
Name: www.jdcdn.com
Address: 61.174.55.1
DNS抓包分析
說了這麼多,有些同學可能還是覺得只有概念,沒法完全理解。所以,我們還是來點實戰更為實際,這也是我更進一步瞭解DNS的工作方式,因為在我看來想了解根本,最有效的方法是抓包,然後深入查探DNS的packet。
本文都會使用Wireshark,相信大家都用過這個工具吧。如果沒用過,可以下載一個,入門很簡單的,別擔心。
A記錄
下面是抓包圖,過濾條件是dns,即protocol為DNS。
請參看第89和90包,這是查詢 www.jd.com 的request和response。
第89包細節圖如下:
我們可以看到上圖,Name是 www.jd.com , Type是A記錄。
另外,我們可以看到其他資訊, DNS是通過UDP傳送。其實,有時候也是通過TCP來傳送。那麼什麼時候用TCP,什麼時候用UDP?很簡單,當response的packet大於512位元組時,就用TCP,反之,則用UDP。再回頭看著89包,長度為70,所以用UDP了 。那多問一個問題,什麼情況下DNS查詢包超過512?CNAME就有可能。可以參考下面的CNAME抓包。
埠是多少呢?53,是的, DNS用的是53埠,非常重要 ,一般防火牆要開啟,否則DNS解析不了,也意味著無法訪問域名的website。
那麼返回什麼呢?繼續看第90包。
我們可以看到 www.jd.com 的DNS A記錄,IP地址是61.174.55.1。
CNAME
下圖是查詢 www.taobao.com 的抓包。
我們看到 www.taobao.com 轉到了 www.taobao.com.danuoyi.tbcache.com 。
同時我們也可以看到 www.taobao.com.danuoyi.tbcache.com 有多條A記錄,這裡就是傳說的DNS 負載均衡。

DNS標準和協議
DNS是有標準和協議的,就跟HTTP類似的。DNS標準和協議在IETF裡。大家可以參考 https://en.wikipedia.org/wiki/Domain_Name_System 的 RFC documents部分。
我認為學習協議,框架,或技術,最佳的方法就是閱讀官方資料。例如,這裡學習DNS可以直接看RFC文件,學習Angular,可以訪問其官網。
DNS 10問
如果面試,下面10問基本可以覆蓋全了,答案在上面已經說過了:
1. 為什麼要用域名?
2. DNS解析的基本流程?
3. DNS的根域名是什麼,有幾個Server?TLD DNS是什麼?
4. DNS的優化策略是什麼?在各個環節怎麼做的?Chrome和各個作業系統怎麼做的?
5. DNS負載均衡是什麼,為什麼要用?
6. DNS的記錄型別有哪些?CNAME一般用在哪些場合?舉例子說明一下。
7. DNS的常用工具和命令有哪些?
8. DNS查詢是用TCP還是UDP?一般用哪個埠?
9. DNS抓包抓過嗎?Wireshark有用過嗎?
10. 請說明一下 www.google.com 和google.com的區別,如何設定它們的DNS?
本章介紹完DNS,下一章節介紹TCP/IP,三次握手,四次揮手,以及SSL/TLS,內容絕對不能錯過。