基本概念
URL(Uniform Resource Location)統一資源定位符 : 俗稱網頁地址, 是因特網上標準的資源地址(Address), 用于定位互聯網上的資源。
IP(Internet Protocol) : 網絡之間互聯的協議, 鏈接互聯網的每一臺設備都有且只有一個IP地址,用來標識自己。
DNS(Domain Name System): 因特網上作為域名和IP地址相互映射的一個分布式數據庫,能夠使用戶更方便的訪問互聯網,而不用去記住能夠被機器直接讀取的IP數串。通過主機名,最終得到該主機名對應的IP地址的過程叫做域名解析(或主機名解析)。
從URL輸入到頁面展示的過程
1、輸入地址
當我們開始在瀏覽器中輸入網址的時候,瀏覽器其實就已經在智能的匹配可能的 URL了,他會從歷史記錄、書簽等地方,找到已經輸入的字符串可能對應的 URL,然后給出智能提示,讓你可以補全URL地址。對于 chrome 瀏覽器,他甚至會直接從緩存中把網頁展示出來,就是說,你還沒有按下 enter,頁面就出來了。
2、瀏覽器查找域名的ip地址
瀏覽器的第一步是通過訪問的域名找出其IP地址,DNS查找過程如下:
- 查詢瀏覽器本身DNS緩存中是否有域名相關的信息
- 查詢本機的host文件中是否有域名相關的信息
- 查詢離本地最近的路由器中DNS的緩存中是否有域名相關的信息
- 查詢ISP(互聯網服務提供商,例如電信,移動)中的DNS服務器中是否有目標域名的信息
- 查詢根域名服務器是否有目標域名的信息,如果沒有,則傳至子域名服務器進行查詢, 以此遞推,直到找到了IP地址為止。
3、瀏覽器向 web 服務器發送一個 HTTP 請求
拿到域名對應的IP地址之后,瀏覽器會以一個隨機端口(1024<端口<65535)向服務器的WEB程序(常用的有httpd,nginx等)80端口發起TCP的連接請求。這個連接請求到達服務器端后(這中間通過各種路由設備,局域網內除外),進入到網卡,然后是進入到內核的TCP/IP協議棧(用于識別該連接請求,解封包,一層一層的剝開),還有可能要經過Netfilter防火墻(屬于內核的模塊)的過濾,最終到達WEB程序,最終建立了TCP/IP的連接。
建立了TCP連接之后,發起一個http請求。一個典型的 http request header 一般需要包括請求的方法,例如 GET 或者 POST 等,不常用的還有 PUT 和 DELETE 、HEAD、OPTION以及 TRACE 方法,一般的瀏覽器只能發起 GET 或者 POST 請求。
拓展知識
1)TCP三次握手
第一次握手:客戶端將標志位SYN置為1,隨機產生一個值為seq=J的數據包到服務器,客戶端進入SYN_SENT狀態,等待服務端確認;
第二次握手:服務端收到數據包后由標志位SYN=1知道客戶端請求建立連接,服務端將標志位SYN和ACK都置為1,ack=J+1,隨機產生一個值seq=K,并將該數據包發送給客戶端以確認連接請求,服務端進入SYN_RCVD狀態。
第三次握手:客戶端收到確認后,檢查ack是否為J+1,ACK是否為1,如果正確則將標志位ACK置為1,ack=K+1,并將該數據包發送給服務端,服務端檢查ack是否為K+1,ACK是否為1,如果正確則連接建立成功,客戶端和服務端進入ESTABLISHED狀態,完成三次握手,隨后客戶端與服務端之間可以開始傳輸數據了。
2)為什需要三次握手?
《計算機網絡》第四版中講“三次握手”的目的是“為了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤”。
書中的例子是這樣的,“已失效的連接請求報文段”的產生在這樣一種情況下:client發出的第一個連接請求報文段并沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以后的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段后,就誤認為是client再次發出的一個新的連接請求。于是就向client發出確認報文段,同意建立連接。
假設不采用“三次握手”,那么只要server發出確認,新的連接就建立了。由于現在client并沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送數據。但server卻以為新的運輸連接已經建立,并一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。采用“三次握手”的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由于收不到確認,就知道client并沒有要求建立連接。”。主要目的防止server端一直等待,浪費資源。
3)TCP四次揮手
第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN_WAIT_1狀態。
第二次揮手:Server收到FIN后,發送一個ACK給Client,確認序號為收到序號+1(與SYN相同,一個FIN占用一個序號),Server進入CLOSE_WAIT狀態。
第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態。
第四次揮手:Client收到FIN后,Client進入TIME_WAIT狀態,接著發送一個ACK給Server,確認序號為收到序號+1,Server進入CLOSED狀態,完成四次揮手。
4)為什么建立連接是三次握手,而關閉連接卻是四次揮手呢?
這是因為服務端在LISTEN狀態下,收到建立連接請求的SYN報文后,把ACK和SYN放在一個報文里發送給客戶端。而關閉連接時,當收到對方的FIN報文時,僅僅表示對方不再發送數據了但是還能接收數據,己方也未必全部數據都發送給對方了,所以己方可以立即close,也可以發送一些數據給對方后,再發送FIN報文給對方來表示同意現在關閉連接,因此,己方ACK和FIN一般都會分開發送。
4、服務器的永久重定向響應
服務器給瀏覽器響應一個301永久重定向響應,這樣瀏覽器就會訪問“http://www.facebook.com/” 而非"http://facebook.com/" 。
為什么服務器一定要重定向而不是直接發會用戶想看的網頁內容呢?
其中一個原因跟搜索引擎排名有 關。你看,如果一個頁面有兩個地址,就像"http://www.igoro.com/" 和"http://igoro.com/", 搜索引擎會認為它們是兩個網站,結果造成每一個的搜索鏈接都減少從而降低排名。而搜索引擎知道301永久重定向是 什么意思,這樣就會把訪問帶www的和不帶www的地址歸到同一個網站排名下。
還有一個是用不同的地址會造成緩存友好性變差。當一個頁面有好幾個名字時,它可能會在緩存里出現好幾次。
5、瀏覽器跟蹤重定向地址
現在,瀏覽器知道了“http://www.facebook.com/” 才是要訪問的正確地址,所以它會發送另一個獲取請求。
6、服務器處理請求
web server接受用戶的請求,并返回代碼。web server 擔任管控的角色,對于不同用戶發送的請求,會結合配置文件,把不同請求委托給服務器上處理對應請求的程序進行處理(例如CGI腳本,JSP腳本,servlets,ASP腳本,服務器端JavaScript,或者一些其它的服務器端技術等)。
7、服務器返回一個 HTTP 響應
經過前面6個步驟,服務器收到了我們的請求,也處理了我們的請求,到這一步,它會把它的處理結果返回,也就是返回一個HTTP響應。
8、瀏覽器顯示 HTML
在瀏覽器沒有完整接受全部HTML文檔時,它就已經開始顯示頁面了,瀏覽器是如何把頁面呈現在屏幕上的呢?就是瀏覽器解析的一個過程,
對應就是html頁面加載、解析、渲染的工作。
- 加載
瀏覽器對一個html頁面的加載順序是從上而下的,并在加載過程并行進行解析渲染處理。在這個過程中遇到link標簽、image標簽、script標簽時,瀏覽器會再次向服務器發送請求獲取css文件、圖片資源、js文件,并執行js代碼,同步進行加載解析。 - 解析、渲染
解析的過程,其實就是生成解析樹,即dom樹。dom樹是由dom元素及屬性節點組成,加上css解析的樣式對象和js解析后的動作實現。而渲染,就是將DOM樹進行可視化表示。 - 繪制網頁
瀏覽器通過上面步驟計算得到渲染樹,是DOM樹的可視化表示,構建渲染樹使頁面以正確的順序繪制出來,遵循一定的渲染規則,經過一系列的渲染工作,實現網站頁面的繪制,由此最終完成了頁面展示。
9、瀏覽器發送請求獲取嵌入在 HTML 中的資源(如圖片、音頻、視頻、CSS、JS等等)
其實這個步驟可以并列在步驟8中,在瀏覽器顯示HTML時,它會注意到需要獲取其他地址內容的標簽。這時,瀏覽器會發送一個獲取請求來重新獲得這些文件。比如我要獲取外圖片,CSS,JS文件等,類似于下面的鏈接:
圖片:http://static.ak.fbcdn.net/rsrc.php/z12E0/hash/8q2anwu7.gif
CSS式樣表:http://static.ak.fbcdn.net/rsrc.php/z448Z/hash/2plh8s4n.css
JavaScript 文件:http://static.ak.fbcdn.net/rsrc.php/zEMOA/hash/c8yzb6ub.js
這些地址都要經歷一個和HTML讀取類似的過程。所以瀏覽器會在DNS中查找這些域名,發送請求,重定向等等...
不像動態頁面,靜態文件會允許瀏覽器對其進行緩存。有的文件可能會不需要與服務器通訊,而從緩存中直接讀取。服務器的響應中包含了靜態文件保存的期限 信息,所以瀏覽器知道要把它們緩存多長時間。還有,每個響應都可能包含像版本號一樣工作的ETag頭(被請求變量的實體值),如果瀏覽器觀察到文件的版本 ETag信息已經存在,就馬上停止這個文件的傳輸。
參考資料
http://www.cnblogs.com/xianyulaodi/p/6547807.html
http://blog.csdn.net/wdzxl198/article/details/11265475
http://www.cnblogs.com/wenanry/archive/2010/02/25/1673368.html
http://www.cnblogs.com/zhaobw/p/6580241.html