1. 程式人生 > >web前端開發:Http協議

web前端開發:Http協議

超文字傳送協議 (HTTP-Hypertext transfer protocol) 定義了瀏覽器(即全球資訊網客戶程序)怎樣向全球資訊網伺服器請求全球資訊網文件,以及伺服器怎樣把文件傳送給瀏覽器。從層次的角度看,HTTP是面向(transaction-oriented)應用層協議,它是全球資訊網上能夠可靠地交換檔案(包括文字、聲音、影象等各種多媒體檔案)的重要基礎。

一、從輸入URL到頁面載入完成的過程中都發生了什麼事情?
0.輸入URL
1.解析URL:把URL分割成幾個部分:協議、網路地址、資源路徑;
2.瀏覽器查詢域名的 IP 地址:如果URL合法,首先它會在DNS本地快取表中查詢,如果有則直接使用 hosts 檔案裡面的 ip 地址。如果沒有則會向 dns 域名解析伺服器發起域名解析請求,如果沒有就會向它的上級伺服器詢問,如此遞迴查詢找到對應的IP後,返回給瀏覽器。
3 . 建立TCP連線:當獲取IP之後,瀏覽器在傳輸層發起一條到達伺服器的 tcp 連線,就開始與所請求的Tcp建立三次握手連線,連線建立後,就向伺服器發出HTTP請求。
4.構造併發送HTTP請求:一個典型的 http request header 一般需要包括請求的方法,例如 GET 或者 POST 等,之後瀏覽器傳送了一空白行來通知伺服器,它已經結束了該頭資訊的傳送。
5.伺服器接受並處理HTTP報文
6.伺服器構造併發送響應報文
7.瀏覽器接收報文,並開始構建頁面
8.關閉TCP連線:一旦Web伺服器向瀏覽器傳送了請求資料,它就要關閉TCP連線,然後如果瀏覽器或者伺服器在其頭資訊加入了這行程式碼
Connection:keep-alive
TCP連線在傳送後將仍然保持開啟狀態,於是,瀏覽器可以繼續通過相同的連線傳送請求。保持連線節省了為每個請求建立新連線所需的時間,還節約了網路頻寬。
9.開始根據資源的型別,將資源組織成螢幕上顯示的影象,這個過程叫渲染,網頁渲染是瀏覽器最複雜、最核心的功能。
10.將渲染好的頁面影象顯示出來,並開始響應使用者的操作。

處理網路響應與渲染。響應到達瀏覽器之後,瀏覽器首先判斷狀態碼,如果是 200 開頭的就好辦,直接進入渲染流程,如果是 300 開頭的就要去相應頭裡面找 location 域,根據這個 location 的指引,進行跳轉,這裡跳轉需要開啟一個跳轉計數器,是為了避免兩個或者多個頁面之間形成的迴圈的跳轉,當跳轉次數過多之後,瀏覽器會報錯,同時停止。如果是 400 開頭或者 500 開頭的狀態碼,瀏覽器也會給出一個錯誤頁面;
當瀏覽得到一個正確的 200 響應之後,先進行多國語言的編碼解析;解決了字符集的問題,接下來就是構建 dom 樹,再接著根據 dom 樹和 css 樣式表來構造 render 樹, 這個才是真正的用於渲染到頁面上的一個一個的矩形框的樹,對於 render 樹上每一個框,需要確定他的 x y 座標,尺寸,邊框,字型,形態,等等諸多方面的東西,render 樹一旦構建完成,整個頁面也就準備好了

需要說明的是,下載頁面,構建 dom 樹,構建 render 樹這三個步驟,實際上並不是嚴格的先後順序的,為了加快速度,提高效率,讓使用者不要等那麼久,現在一般都並行的往前推進的,現代的瀏覽器都是一邊下載,下載到了一點資料就開始構建 dom 樹,也一邊開始構建 render 樹,構建了一點就顯示一點出來,這樣使用者看起來就不用等待那麼久了
構建 dom 樹的過程中,如果遇到了由 script 標籤包起來的 js 動態指令碼程式碼,那麼會把程式碼送到 js 引擎裡面去跑,如果遇到了 style 標籤包圍起來的 css 程式碼,也會儲存下來,用於稍後的渲染。如果遇到了 img 等引用外部檔案的標籤,那麼瀏覽器會根據指定的 url 再次發起一個新的 http 請求,去把這個檔案拉取回來,值得一提的是,對於同一個域名下的下載過程來說,瀏覽器一般允許的併發請求是有限的,通常控制在兩個左右,所以如果有很多的圖片的話,一般出於優化的目的,都會把這些圖片使用一臺靜態檔案的伺服器來儲存起來,負責響應,從而減少主伺服器的壓力。

二、HTTP協議之URL
http(超文字傳輸協議)是一個基於請求與響應模式的、無狀態的、應用層的協議,常基於TCP的連線方式
http協議中規定了一個特殊規則:瀏覽器對一個伺服器不能同時開啟兩個以上的連線(IP+Port)。這個規則應該是為了保護伺服器不會很容易被洪水攻擊。

1、HTTP URL的格式如下:http://host[":"port][abs_path]
 http表示要通過HTTP協議來定位網路資源;
 host表示合法的Internet主機域名或者IP地址;
 port指定一個埠號,為空則使用預設埠 80;
 abs_path指定請求資源的URI;如果URL中沒有給出abs_path,那麼當它作為請求URI時,必須以“/”的形式給出,通常這個工作瀏覽器自動幫我們完成。
DEMO:輸入:www.sina.com.cn,瀏覽器自動轉換成:http://www.sina.com.cn /

2、URL編碼
foo://example.com:8042/over/there?name=ferret#nose
\_/ \___________________/ \__________/\___________/ \__/
scheme —— authority — path — query —fragment

注意:
Url引數字串中使用key=value鍵值對這樣的形式來傳參
Url中只允許包含英文字母(a-zA-Z)、數字(0-9)、- _ . ~4個特殊字元以及所有保留字元。
Url中只允許使用可列印字元。US-ASCII碼中的10-7F位元組全都表示控制字元,這些字元都不能直接出現在Url中。同時,對於80-FF位元組(ISO-8859-1),由於已經超出了US-ACII定義的位元組範圍,因此也不可以放在Url中。

3、有一些字元(:/?#[]@)是用作分隔不同元件的。
:冒號用於分隔協議和主機,/用於分隔主機和路徑,?用於分隔路徑和查詢引數,等等。還有一些字元(!$&’()*+,;=)用於在每個元件中起到分隔作用的,如=用於表示查詢引數中的鍵值對,&符號用於分隔查詢多個鍵值對。當元件中的普通資料包含這些特殊字元時,需要對其進行編碼。

RFC3986中指定了以下字元為保留字元:

! * ’ ( ) ; : @ & = + $ , / ? # [ ]

還有一些字元,當他們直接放在Url中的時候,可能會引起解析程式的歧義。這些字元被視為不安全字元,原因有很多。

 空格:Url在傳輸的過程,或者使用者在排版的過程,或者文字處理程式在處理Url的過程,都有可能引入無關緊要的空格,或者將那些有意義的空格給去掉
 引號以及<>:引號和尖括號通常用於在普通文字中起到分隔Url的作用
 # :通常用於表示書籤或者錨點
 % :百分號本身用作對不安全字元進行編碼時使用的特殊字元,因此本身需要編碼
 {}|\^[]`~:某一些閘道器或者傳輸代理會篡改這些字元

需要注意的是,對於Url中的合法字元,編碼和不編碼是等價的,但是對於上面提到的這些字元,如果不經過編碼,那麼它們有可能會造成Url語義的不同。因此對於Url而言,只有普通英文字元和數字,特殊字元$-_.+!*’()還有保留字元,才能出現在未經編碼的Url之中。其他字元均需要經過編碼之後才能出現在Url中。

4.如何對Url中的非法字元進行編碼
Url編碼通常也被稱為百分號編碼:使用%百分號加上兩位的字元——0123456789ABCDEF——代表一個位元組的十六進位制形式。Url編碼預設使用的字符集是US-ASCII。例如a在US-ASCII碼中對應的位元組是0x61,那麼Url編碼之後得到的就是%61,我們在位址列上輸入http://g.cn/search?q=%61%62%63,實際上就等同於在google上搜索abc了。又如@符號在ASCII字符集中對應的位元組為0x40,經過Url編碼之後得到的是%40。
這裡寫圖片描述
1) 對於非ASCII字元,需要使用ASCII字符集的超集進行編碼得到相應的位元組,然後對每個位元組執行百分號編碼。對於Unicode字元,RFC文件建議使用utf-8對其進行編碼得到相應的位元組,然後對每個位元組執行百分號編碼。如“中文”使用UTF-8字符集得到的位元組為0xE4 0xB8 0xAD 0xE6 0x96 0x87,經過Url編碼之後得到“%E4%B8%AD%E6%96%87”。
2) 如果某個位元組對應著ASCII字符集中的某個非保留字元,則此位元組無需使用百分號表示。例如“Url編碼”,使用UTF-8編碼得到的位元組是0x55 0x72 0x6C 0xE7 0xBC 0x96 0xE7 0xA0 0x81,由於前三個位元組對應著ASCII中的非保留字元“Url”,因此這三個位元組可以用非保留字元“Url”表示。最終的Url編碼可以簡化成“Url%E7%BC%96%E7%A0%81”,當然,如果你用”%55%72%6C%E7%BC%96%E7%A0%81”也是可以的。

Javascript中提供了3對函式用來對Url編碼以得到合法的Url,它們分別是escape / unescape,encodeURI / decodeURI和encodeURIComponent / decodeURIComponent。

三、HTTP協議之請求

如果某項請求傳送到您的伺服器要求顯示您網站上的某個網頁(例如,使用者通過瀏覽器訪問您的網頁或 Googlebot 抓取網頁時),伺服器將會返回 HTTP 狀態碼響應請求。
此狀態碼提供關於請求狀態的資訊,告訴 Googlebot 關於您的網站和請求的網頁的資訊。
一些常見的狀態碼為:
200 – 伺服器成功返回網頁
404 – 請求的網頁不存在
503 – 伺服器超時
下面提供 HTTP 狀態碼的完整列表。點選連結可瞭解詳情。您也可以訪問 HTTP 狀態碼上的 W3C 頁獲取更多資訊。
1xx(臨時響應)
表示臨時響應並需要請求者繼續執行操作的狀態碼。
100(繼續) 請求者應當繼續提出請求。伺服器返回此程式碼表示已收到請求的第一部分,正在等待其餘部分。
101(切換協議) 請求者已要求伺服器切換協議,伺服器已確認並準備切換。
2xx (成功)
表示成功處理了請求的狀態碼。
200(成功) 伺服器已成功處理了請求。通常,這表示伺服器提供了請求的網頁。如果是對您的 robots.txt 檔案顯示此狀態碼,則表示 Googlebot 已成功檢索到該檔案。
201(已建立) 請求成功並且伺服器建立了新的資源。
202(已接受) 伺服器已接受請求,但尚未處理。
203(非授權資訊) 伺服器已成功處理了請求,但返回的資訊可能來自另一來源。
204(無內容) 伺服器成功處理了請求,但沒有返回任何內容。
205(重置內容) 伺服器成功處理了請求,但沒有返回任何內容。與 204 響應不同,此響應要求請求者重置文件檢視(例如,清除表單內容以輸入新內容)。
206(部分內容) 伺服器成功處理了部分 GET 請求。
3xx (重定向)
要完成請求,需要進一步操作。通常,這些狀態碼用來重定向。Google 建議您在每次請求中使用重定向不要超過 5 次。您可以使用網站管理員工具檢視一下 Googlebot 在抓取重定向網頁時是否遇到問題。診斷下的網路抓取頁列出了由於重定向錯誤導致 Googlebot 無法抓取的網址。
300(多種選擇) 針對請求,伺服器可執行多種操作。伺服器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。
301(永久移動) 請求的網頁已永久移動到新位置。伺服器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。您應使用此程式碼告訴 Googlebot 某個網頁或網站已永久移動到新位置。
302(臨時移動) 伺服器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來響應以後的請求。此程式碼與響應 GET 和 HEAD 請求的 301 程式碼類似,會自動將請求者轉到不同的位置,但您不應使用此程式碼來告訴 Googlebot 某個網頁或網站已經移動,因為 Googlebot 會繼續抓取原有位置並編制索引。
303(檢視其他位置) 請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,伺服器返回此程式碼。對於除 HEAD 之外的所有請求,伺服器會自動轉到其他位置。
304(未修改)
自從上次請求後,請求的網頁未修改過。伺服器返回此響應時,不會返回網頁內容。
如果網頁自請求者上次請求後再也沒有更改過,您應將伺服器配置為返回此響應(稱為 If-Modified-Since HTTP 標頭)。伺服器可以告訴 Googlebot 自從上次抓取後網頁沒有變更,進而節省頻寬和開銷。

305(使用代理) 請求者只能使用代理訪問請求的網頁。如果伺服器返回此響應,還表示請求者應使用代理。
307(臨時重定向) 伺服器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來響應以後的請求。此程式碼與響應 GET 和 HEAD 請求的 301 程式碼類似,會自動將請求者轉到不同的位置,但您不應使用此程式碼來告訴 Googlebot 某個頁面或網站已經移動,因為 Googlebot 會繼續抓取原有位置並編制索引。
4xx(請求錯誤)
這些狀態碼錶示請求可能出錯,妨礙了伺服器的處理。
400(錯誤請求) 伺服器不理解請求的語法。
401(未授權) 請求要求身份驗證。對於登入後請求的網頁,伺服器可能返回此響應。
403(禁止) 伺服器拒絕請求。如果您在 Googlebot 嘗試抓取您網站上的有效網頁時看到此狀態碼(您可以在 Google 網站管理員工具診斷下的網路抓取頁面上看到此資訊),可能是您的伺服器或主機拒絕了 Googlebot 訪問。
404(未找到)
伺服器找不到請求的網頁。例如,對於伺服器上不存在的網頁經常會返回此程式碼。
如果您的網站上沒有 robots.txt 檔案,而您在 Google 網站管理員工具“診斷”標籤的 robots.txt 頁上看到此狀態碼,則這是正確的狀態碼。但是,如果您有 robots.txt 檔案而又看到此狀態碼,則說明您的 robots.txt 檔案可能命名錯誤或位於錯誤的位置(該檔案應當位於頂級域,名為 robots.txt)。
如果對於 Googlebot 抓取的網址看到此狀態碼(在”診斷”標籤的 HTTP 錯誤頁面上),則表示 Googlebot 跟隨的可能是另一個頁面的無效連結(是舊連結或輸入有誤的連結)。
405(方法禁用) 禁用請求中指定的方法。
406(不接受) 無法使用請求的內容特性響應請求的網頁。
407(需要代理授權) 此狀態碼與 401(未授權)類似,但指定請求者應當授權使用代理。如果伺服器返回此響應,還表示請求者應當使用代理。
408(請求超時) 伺服器等候請求時發生超時。
409(衝突) 伺服器在完成請求時發生衝突。伺服器必須在響應中包含有關衝突的資訊。伺服器在響應與前一個請求相沖突的 PUT 請求時可能會返回此程式碼,以及兩個請求的差異列表。
410(已刪除) 如果請求的資源已永久刪除,伺服器就會返回此響應。該程式碼與 404(未找到)程式碼類似,但在資源以前存在而現在不存在的情況下,有時會用來替代 404 程式碼。如果資源已永久移動,您應使用 301 指定資源的新位置。
411(需要有效長度) 伺服器不接受不含有效內容長度標頭欄位的請求。
412(未滿足前提條件) 伺服器未滿足請求者在請求中設定的其中一個前提條件。
413(請求實體過大) 伺服器無法處理請求,因為請求實體過大,超出伺服器的處理能力。
414(請求的 URI 過長) 請求的 URI(通常為網址)過長,伺服器無法處理。
415(不支援的媒體型別) 請求的格式不受請求頁面的支援。
416(請求範圍不符合要求) 如果頁面無法提供請求的範圍,則伺服器會返回此狀態碼。
417(未滿足期望值) 伺服器未滿足”期望”請求標頭欄位的要求。
5xx(伺服器錯誤)
這些狀態碼錶示伺服器在處理請求時發生內部錯誤。這些錯誤可能是伺服器本身的錯誤,而不是請求出錯。
500(伺服器內部錯誤) 伺服器遇到錯誤,無法完成請求。
501(尚未實施) 伺服器不具備完成請求的功能。例如,伺服器無法識別請求方法時可能會返回此程式碼。
502(錯誤閘道器) 伺服器作為閘道器或代理,從上游伺服器收到無效響應。
503(服務不可用) 伺服器目前無法使用(由於超載或停機維護)。通常,這只是暫時狀態。
504(閘道器超時) 伺服器作為閘道器或代理,但是沒有及時從上游伺服器收到請求。
505(HTTP 版本不受支援) 伺服器不支援請求中所用的 HTTP 協議版本。
合理利用這些狀態碼,避免錯誤利用,必將會為你的網站帶來更佳的瀏覽者體會,為你的網站發展,奠定堅實的發展基礎。