HTTP 無狀態性html
HTTP 協議是無狀態的(stateless)。也就是說,同一個客戶端第二次訪問同一個服務器上的頁面時,服務器沒法知道這個客戶端曾經訪問過,服務器也沒法分辨不一樣的客戶端。HTTP 的無狀態特性簡化了服務器的設計,使服務器更容易支持大量併發的HTTP 請求。web
HTTP 持久鏈接windows
HTTP1.0 使用的是非持久鏈接,主要缺點是客戶端必須爲每個待請求的對象創建並維護一個新的鏈接,即每請求一個文檔就要有兩倍RTT 的開銷。由於同一個頁面可能存在多個對象,因此非持久鏈接可能使一個頁面的下載變得十分緩慢,並且這種短鏈接增長了網絡傳輸的負擔。HTTP1.1 使用持久鏈接keepalive,所謂持久鏈接,就是服務器在發送響應後仍然在一段時間內保持這條鏈接,容許在同一個鏈接中存在屢次數據請求和響應,即在持久鏈接狀況下,服務器在發送完響應後並不關閉TCP 鏈接,而客戶端能夠經過這個鏈接繼續請求其餘對象。瀏覽器
HTTP/1.1 協議的持久鏈接有兩種方式:緩存
非流水線方式:客戶在收到前一個響應後才能發出下一個請求;服務器
流水線方式:客戶在收到 HTTP 的響應報文以前就能接着發送新的請求報文;cookie
一、首先,在瀏覽器裏輸入網址:網絡
二、瀏覽器根據域名解析IP地址:併發
瀏覽器根據訪問的域名找到其IP地址。DNS查找過程以下:
1)瀏覽器緩存:瀏覽器會緩存DNS記錄一段時間。 但操做系統沒有告訴瀏覽器儲存DNS記錄的時間,這樣不一樣瀏覽器會儲存個自固定的一個時間(2分鐘到30分鐘不等)。
2)系統緩存:若是在瀏覽器緩存裏沒有找到須要的域名,瀏覽器會作一個系統調用(windows裏是gethostbyname),這樣即可得到系統緩存中的記錄。
3)路由器緩存:若是系統緩存也沒找到須要的域名,則會向路由器發送查詢請求,它通常會有本身的DNS緩存。
4)ISP DNS緩存:若是依然沒找到須要的域名,則最後要查的就是ISP緩存DNS的服務器。在這裏通常都能找到相應的緩存記錄。app
域名解析原理:
1>一個域中的每一個主機名與其IP地址的映射關係由這個域的DNS服務器負責管理,例如,"www.it.org」、「ftp.it.org」、「blog.it.org」等主機名都由管理域「it.org」的DNS服務器進行管理,而不能由管理域「org」的DNS服務器進行管理。
2>每一個管理域都必須在其直接父域的DNS服務器上註冊該子域的名稱和該子域的DNS服務器的IP地址,例如,必須在管理域「org」的DNS服務器註冊子域「it.org」和其DNS服務器的IP地址後,域名「it.org」才能真正被外界所承認。
3>爲了方便對頂級域名的統一管理,在頂級域名之上其實還有一個根域名,根域名用點(.)表示,例如,「www.it.org」也能夠寫爲「www.it.org.」,「www.it.org.」中的最後的那個點(.)就表示根域名。 Internet中的根域名由InterNIC(國際互聯網絡信息中心)集中管理,頂級域名和其下的域名則由擁有該域名的組織、公司和我的本身管理。
域名解析的方式主要有兩種,分別是:
或者
DNS有一個弊端,一個域名看上去只是對應一個單獨的IP地址。還好有幾種方法能夠消除這個瓶頸:
1>循環 DNS 是DNS查找時返回多個IP時的解決方案。舉例來講,facebook.com實際上就對應了四個IP地址。
2>負載平衡器是以一個特定IP地址進行偵聽並將網絡請求轉發到集羣服務器上的硬件設備。 一些大型的站點通常都會使用這種昂貴的高性能負載平衡器。
3>地理 DNS 根據用戶所處的地理位置,經過把域名映射到多個不一樣的IP地址提升可擴展性。這樣不一樣的服務器不可以更新同步狀態,但映射靜態內容的話很是好。
4>Anycast 是一個IP地址映射多個物理主機的路由技術。 美中不足的是Anycast與TCP協議適應的不是很好,因此不多應用在那些方案中。大多數DNS服務器使用Anycast來得到高效低延遲的DNS查找。
三、瀏覽器與web服務器創建一個TCP鏈接
四、瀏覽器給web服務器發送一個http請求:
一個http請求報文由請求行<request-line>、請求頭部<headers>、空行<blank-line>
和請求數據<request-body>4個部分組成,請求報文的通常格式以下圖:
1)請求行:由請求方法、URL和HTTP協議版本3個字段組成,它們用空格分隔。例如,GET /index.html HTTP/1.1。HTTP協議的請求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。而常見的有以下幾種:
1>GET:當客戶端要從服務器中讀取文檔時,當點擊網頁上的連接或者經過在瀏覽器的地址欄輸入網址來瀏覽網頁的,使用的都是GET方式。GET方法要求服務器將URL定位的資源放在響應報文的數據部分,回送給客戶端。使用GET方法時,請求參數和對應的值附加在URL後面,利用一個問號(「?」)表明URL的結尾與請求參數的開始,傳遞參數長度受限制。例如,/index.jsp?id=100&op=bind。經過GET方式傳遞的數據直接放在在地址中,因此GET方式的請求通常不包含」請求內容」部分,請求數據以地址的形式表如今請求行。地址中」?」以後的部分就是經過GET發送的請求數據,咱們能夠在地址欄中清楚的看到,各個數據之間用」&」符號隔開。顯然這種方式不適合傳送私密數據。另外,因爲不一樣的瀏覽器對地址的字符限制也有所不一樣,通常最多隻能識別1024個字符,因此若是須要傳送大量數據的時候,也不適合使用GET方式。若是數據是英文字母/數字,原樣發送,若是是空格,轉換爲+,若是是中文/其餘字符,則直接把字符串用BASE64加密,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX爲該符號以16進製表示的ASCII。
2>POST:容許客戶端給服務器提供信息較多。POST方法將請求參數封裝在HTTP請求數據中,以名稱/值的形式出現,能夠傳輸大量數據,這樣POST方式對傳送的數據大小沒有限制,並且也不會顯示在URL中。POST方式請求行中不包含數據字符串,這些數據保存在「請求內容」部分,各數據之間也是使用」&「符號隔開。POST方式大多用於頁面的表單中。由於POST也能完成GET的功能,所以多數人在設計表單的時候一概都使用POST方式,其實這是一個誤區。GET方式也有本身的特色和優點,咱們應該根據不一樣的狀況來選擇是使用GET仍是使用POST。
3>HEAD:就像GET,只不過服務端接受到HEAD請求後只返回響應頭,而不會發送響應內容。當咱們只須要查看某個頁面的狀態的時候,使用HEAD是很是高效的,由於在傳輸的過程當中省去了頁面內容。
2)請求頭部:由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號」:「分隔。請求頭部通知服務器有關於客戶端請求的信息,典型的請求頭有:
User-Agent:產生請求的瀏覽器類型。
Accept:客戶端可識別的內容類型列表。星號 「 * 」 用於按範圍將類型分組,用 「 */* 」 指示可接受所有類型,用「 type/* 」指示可接受 type 類型的全部子類型。
Host:要請求的主機名,容許多個域名同處一個IP地址,即虛擬主機。
Accept-Language:客戶端可接受的天然語言。
Accept-Encoding:客戶端可接受的編碼壓縮格式。
Accept-Charset:可接受的應答的字符集。
connection:鏈接方式(close 或 keepalive)。
Cookie:存儲於客戶端擴展字段,向同一域名的服務端發送屬於該域的cookie。
3)空行:最後一個請求頭部以後是一個空行,發送回車符和換行符,通知服務器如下再也不有請求頭部。
4)請求數據:請求數據不在GET方法中使用,而在POST方法中使用。POST方法適用於須要客戶填寫表單的場合。與請求數據相關的最常使用的請求頭部是Content-Type和Content-Length。
請求報文示例:
五、服務器的永久重定向響應:
服務器給瀏覽器響應一個301永久重定向響應,這樣瀏覽器就會訪問「http://www.facebook.com/」 而非「http://facebook.com/」。爲何服務器必定要重定向而不是直接發送用戶想看的網頁內容呢?其中一個緣由跟搜索引擎排名有關。若是一個頁面有兩個地址,就像http://www.igoro.com/和http://igoro.com/,搜索引擎會認爲它們是兩個網站,結果形成每一個搜索連接都減小從而下降排名。而搜索引擎知道301永久重定向是什麼意思,這樣就會把訪問帶www的和不帶www的地址歸到同一個網站排名下。還有就是用不一樣的地址會形成緩存友好性變差,當一個頁面有好幾個名字時,它可能會在緩存裏出現好幾回。
一個http響應報文由狀態行<status-line>、響應頭部<headers>、空行<blank-line>
和響應數據<response-body>4個部分組成,響應報文的通常格式以下圖:
1)狀態行: 由HTTP協議版本、服務器返回的響應狀態碼和響應狀態碼的文本描述組成。
狀態代碼由三位數字組成,第一個數字定義了響應的類別,且有五種可能取值。
1xx:信息性狀態碼,表示服務器已接收了客戶端請求,客戶端可繼續發送請求。
100 Continue
101 Switching Protocols
2xx:成功狀態碼,表示服務器已成功接收到請求並進行處理。
200 OK 表示客戶端請求成功
204 No Content 成功,但不返回任何實體的主體部分
206 Partial Content 成功執行了一個範圍(Range)請求
3xx:重定向狀態碼,表示服務器要求客戶端重定向。
301 Moved Permanently 永久性重定向,響應報文的Location首部應該有該資源的新URL
302 Found 臨時性重定向,響應報文的Location首部給出的URL用來臨時定位資源
303 See Other 請求的資源存在着另外一個URI,客戶端應使用GET方法定向獲取請求的資源
304 Not Modified 客戶端發送附帶條件的請求(請求首部中包含如If-Modified-Since等指定首部)時,服務端有可能返回304,此時,響應報文中不包含任何報文主體。
307 Temporary Redirect 臨時重定向。與302 Found含義同樣。302禁止POST變換爲GET,但實際使用時並不必定,307則更多瀏覽器可能會遵循這一標準,但也依賴於瀏覽器具體實現
4xx:客戶端錯誤狀態碼,表示客戶端的請求有非法內容。
400 Bad Request 表示客戶端請求有語法錯誤,不能被服務器所理解
401 Unauthonzed 表示請求未經受權,該狀態代碼必須與 WWW-Authenticate 報頭域一塊兒使用
403 Forbidden 表示服務器收到請求,可是拒絕提供服務,一般會在響應正文中給出不提供服務的緣由
404 Not Found 請求的資源不存在,例如,輸入了錯誤的URL
5xx:服務器錯誤狀態碼,表示服務器未能正常處理客戶端的請求而出現意外錯誤。
500 Internel Server Error 表示服務器發生不可預期的錯誤,致使沒法完成客戶端的請求
503 Service Unavailable 表示服務器當前不可以處理客戶端的請求,在一段時間以後,服務器可能會恢復正常
2)響應頭部:由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號」:「分隔,典型的響應頭有:
Location:用於重定向接受者到一個新的位置。例如:客戶端所請求的頁面已不存在原先的位置,爲了讓客戶端重定向到這個頁面新的位置,服務器端能夠發回Location響應報頭後使用重定向語句,讓客戶端去訪問新的域名所對應的服務器上的資源
Server:包含了服務器用來處理請求的軟件信息及其版本。它和 User-Agent 請求報頭域是相對應的,前者發送服務器端軟件的信息,後者發送客戶端軟件(瀏覽器)和操做系統的信息
Vary:指示不可緩存的請求頭列表
Connection:鏈接方式
對於請求來講:close(告訴 WEB 服務器或者代理服務器,在完成本次請求的響應後,斷開鏈接,不等待本次鏈接的後續請求了)。keepalive(告訴WEB服務器或者代理服務器,在完成本次請求的響應後,保持鏈接,等待本次鏈接的後續請求);
對於響應來講:close(鏈接已經關閉); keepalive(鏈接保持着,在等待本次鏈接的後續請求); Keep-Alive:若是瀏覽器請求保持鏈接,則該頭部代表但願WEB 服務器保持鏈接多長時間(秒);例如:Keep-Alive:300;
WWW-Authenticate:必須被包含在401 (未受權的)響應消息中,這個報頭域和前面講到的Authorization 請求報頭域是相關的,當客戶端收到 401 響應消息,就要決定是否請求服務器對其進行驗證。若是要求服務器對其進行驗證,就能夠發送一個包含了Authorization 報頭域的請求
3)空行:最後一個響應頭部以後是一個空行,發送回車符和換行符,通知瀏覽器如下再也不有響應頭部。
4)響應數據:服務器返回給客戶端的文本信息。
響應報文示例:
六、瀏覽器跟蹤重定向地址:
如今瀏覽器知道了 「HTTP://www.facebook.com/」纔是要訪問的正確地址,因此它會發送另外一個http請求。
七、服務器「處理」請求:
服務器接收到獲取請求,而後處理並返回一個響應。這表面上看起來是一個順向的任務,但其實這中間發生了不少有意思的東西,就像做者博客這樣簡單的網站,況且像facebook那樣訪問量大的網站呢!web服務器軟件(像IIS和阿帕奇)接收到HTTP請求,而後肯定執行某一請求處理來處理它。請求處理就是一個可以讀懂請求而且能生成HTML來進行響應的程序(像ASP.NET,PHP,RUBY…)。
八、服務器發回一個HTML響應
九、釋放TCP鏈接
若connection 模式爲close,則服務器主動關閉TCP 鏈接,客戶端被動關閉鏈接,釋放TCP 鏈接;若connection 模式爲keepalive,則該鏈接會保持一段時間,在該時間內能夠繼續接收請求;
十、客戶端瀏覽器解析HTML內容
客戶端將服務器響應的 html 文本解析並顯示
十一、瀏覽器獲取嵌入在HTML中的對象
在瀏覽器顯示HTML時,它會注意到須要獲取其餘地址內容的標籤。這時瀏覽器會發送一個獲取請求來從新得到這些文件。這些地址都要經歷一個和HTML讀取相似的過程。因此瀏覽器會在DNS中查找這些域名,發送請求,重定向等等