做爲互聯網通訊協議的一員老將,HTTP 協議走到今天已經經歷了三次版本的變更,如今最新的版本是 HTTP2.0,相信你們早已耳熟能詳。今天就給你們好好介紹一下 HTTP 的前世此生。
先簡單的介紹一下,後面再具體詳解css
HTTP 的最先版本誕生在 1991 年,這個最先版本和如今比起來極其簡單,沒有 HTTP 頭,沒有狀態碼,甚至版本號也沒有,後來它的版本號才被定爲 0.9 來和其餘版本的 HTTP 區分。HTTP/0.9 只支持一種方法—— Get,請求只有一行。html
GET /hello.html
響應也是很是簡單的,只包含 html 文檔自己。前端
<HTML> Hello world </HTML>
當 TCP 創建鏈接以後,服務器向客戶端返回 HTML 格式的字符串。發送完畢後,就關閉 TCP 鏈接。因爲沒有狀態碼和錯誤代碼,若是服務器處理的時候發生錯誤,只會傳回一個特殊的包含問題描述信息的 HTML 文件。這就是最先的 HTTP/0.9 版本。nginx
1996 年,HTTP/1.0 版本發佈,大大豐富了 HTTP 的傳輸內容,除了文字,還能夠發送圖片、視頻等,這爲互聯網的發展奠基了基礎。相比 HTTP/0.9,HTTP/1.0 主要有以下特性:git
支持傳輸 HTML 文件之外其餘類型的內容 一個典型的 HTTP/1.0 的請求像這樣:github
GET /hello.html HTTP/1.0 User-Agent:NCSA_Mosaic/2.0(Windows3.1) 200 OK Date: Tue, 15 Nov 1996 08:12:31 GMT Server: CERN/3.0 libwww/2.17 Content-Type: text/html <HTML> 一個包含圖片的頁面 <IMGSRC="/smile.gif"> </HTML>
在 HTTP/1.0 發佈幾個月後,HTTP/1.1 就發佈了。HTTP/1.1 更多的是做爲對 HTTP/1.0 的完善,在 HTTP1.1 中,主要具備以下改進:面試
HTTPS 是以安全爲目標的 HTTP 通道,簡單講是 HTTP 的安全版,即 HTTP 下加入 SSL 層,HTTPS 的安全基礎是 SSL,所以加密的詳細內容就須要 SSL。算法
HTTPS 協議的主要做用能夠分爲兩種:一種是創建一個信息安全通道,來保證數據傳輸的安全;另外一種就是確認網站的真實性。 HTTPS 和 HTTP 的區別主要以下:數據庫
在 2010 年到 2015 年,谷歌經過實踐一個實驗性的 SPDY 協議,證實了一個在客戶端和服務器端交換數據的另類方式。其收集了瀏覽器和服務器端的開發者的焦點問題,明確了響應數量的增長和解決複雜的數據傳輸。在啓動 SPDY 這個項目時預設的目標是:segmentfault
爲了達到下降目標,減小頁面加載時間的目標,SPDY 引入了一個新的二進制分幀數據層,以實現多向請求和響應、優先次序、最小化及消除沒必要要的網絡延遲,目的是更有效地利用底層 TCP 鏈接。
時間來到 2015 年,HTTP/2.0 問世。先來介紹一下 HTTP/2.0 的特色吧:
HTTP協議是構建在TCP/IP協議之上的,是TCP/IP協議的一個子集,因此要理解HTTP協議,有必要先了解下TCP/IP協議相關的知識。
TCP/IP協議族是由一個四層協議組成的系統,這四層分別爲:應用層、傳輸層、網絡層和數據鏈路層
分層的好處是把各個相對獨立的功能解耦,層與層之間經過規定好的接口來通訊。若是之後須要修改或者重寫某一個層的實現,只要接口保持不變也不會影響到其餘層的功能。接下來,咱們將會介紹各個層的主要做用。
1) 應用層
應用層通常是咱們編寫的應用程序,其決定了向用戶提供的應用服務。應用層能夠經過系統調用與傳輸層進行通訊。
處於應用層的協議很是多,好比:FTP(File Transfer Protocol,文件傳輸協議)、DNS(Domain Name System,域名系統)和咱們本章討論的HTTP(HyperText Transfer Protocol,超文本傳輸協議)等。
2) 傳輸層
傳輸層經過系統調用嚮應用層提供處於網絡鏈接中的兩臺計算機之間的數據傳輸功能。
在傳輸層有兩個性質不一樣的協議:TCP(Transmission Control Protocol,傳輸控制協議)和UDP(User Data Protocol,用戶數據報協議)。
3) 網絡層
網絡層用來處理在網絡上流動的數據包,數據包是網絡傳輸的最小數據單位。該層規定了經過怎樣的路徑(傳輸路線)到達對方計算機,並把數據包傳輸給對方。IP協議
4) 鏈路層
鏈路層用來處理鏈接網絡的硬件部分,包括控制操做系統、硬件設備驅動、NIC(Network Interface Card,網絡適配器)以及光纖等物理可見部分。硬件上的範疇均在鏈路層的做用範圍以內。
數據包封裝
上層協議數據是如何轉變爲下層協議數據的呢?這是經過封裝(encapsulate)來實現的。應用程序數據在發送到物理網絡以前,會沿着協議棧從上往下傳遞。每層協議都將在上層協議數據的基礎上加上本身的頭部信息(鏈路層還會加上尾部信息),覺得實現該層功能提供必要的信息.
發送端發送數據時,數據會從上層傳輸到下層,且每通過一層都會被打上該層的頭部信息。而接收端接收數據時,數據會從下層傳輸到上層,傳輸前會把下層的頭部信息刪除.
因爲下層協議的頭部信息對上層協議是沒有實際的用途,因此在下層協議傳輸數據給上層協議的時候會把該層的頭部信息去掉,這個封裝過程對於上層協議來講是徹底透明的。這樣作的好處是,應用層只須要關心應用服務的實現,而不用管底層的實現。
TCP三次握手
從上面的介紹可知,傳輸層協議主要有兩個:TCP協議和UDP協議。TCP協議相對於UDP協議的特色是:TCP協議提供面向鏈接、字節流和可靠的傳輸。
當三次握手完成後,TCP協議會爲鏈接雙方維持鏈接狀態。爲了保證數據傳輸成功,接收端在接收到數據包後必須發送ACK報文做爲確認。若是在指定的時間內(這個時間稱爲從新發送超時時間),發送端沒有接收到接收端的ACK報文,那麼就會重發超時的數據。
當你在瀏覽器的地址欄輸入 https://juejin.im 後會發生什麼,你們在心中確定是有一個大概的,這裏我將 DNS 域名解析 這個步驟詳細的講一遍。在講概念以前我先放上一張經典的圖文供你們思考一分鐘。
查找域名對應的 IP 地址的具體過程
列表項目
http工做的簡單過程
一些常見的http請求方法。
關於get與post的一些區別。能夠看個人另外一篇文章面試經典之http中get與post的區別
http很重要的一點還有他的緩存機制。關於這部分的內容能夠看一下我以前的文章瀏覽器緩存看這一篇就夠了。這裏就不在贅述了。
這裏主要講一些經常使用的狀態碼
一、 301 永久轉移
當你想換域名的時候,就可使用301,如以前的域名叫www.renfed.com,後來換了一個新域名fed.renren.com,但願用戶訪問老域名的時候可以自動跳轉到新的域名,那麼就可使用nginx返回301:
server { listen 80; server_name www.renfed.com; root /home/fed/wordpress; return 301 https://fed.renren.com$request_uri; }
瀏覽器收到301以後,就會自動跳轉了。搜索引擎在爬的時候若是發現是301,在若干天以後它會把以前收錄的網頁的域名給換了。
還有一個場景,若是但願訪問http的時候自動跳轉到https也是能夠用301,由於若是直接在瀏覽器地址欄輸入域名而後按回車,前面沒有帶https,那麼是默認的http協議,這個時候咱們但願用戶可以訪問安全的https的,不要訪問http的,因此要作一個重定向,也可使用301,如:
server { listen 80; server_name fed.renren.com; if ($scheme != "https") { return 301 https://$host$request_uri; } }
二、302 Found 資源暫時轉移
不少短連接跳轉長連接就是使用的302,以下圖所示:
三、304 Not Modified 沒有修改
這個主要在上面的緩存哪裏出現的比較多。若是服務器沒有修改。就會使用瀏覽器的緩存。
四、400 Bad Request 請求無效
當必要參數缺失、參數格式不對時,後端一般會返回400,以下圖所示:
五、403 Forbidden 拒絕服務
服務可以理解你的請求,包括傳參正確,可是拒絕提供服務。例如,服務容許直接訪問靜態文件,可是不容許訪問某個目錄:
不然,別人對你服務器上的文件就一覽無遺了。
403和401的區別在於,401是沒有認證,沒有登錄驗證之類的錯誤。
六、500 內部服務器錯誤
如業務代碼出現了異常沒有捕獲,被tomcat捕獲了,就會返回500錯誤:
如:數據庫字段長度限制爲30個字符,若是沒有判斷直接插入一條31個字符的記錄,就會致使數據庫拋異常,若是異常沒有捕獲處理,就直接返回500。
當服務完全掛了,連返回都沒有的時候,那麼就是502了。
七、502 Bad Gateway 網關錯誤
這種狀況是由於nginx收到請求,可是請求沒有打過去,多是由於業務服務掛了,或者是打過去的端口號寫錯了
八、504 Gateway Timeout 網關超時
一般是由於服務處理請求過久,致使超時,如PHP服務默認的請求響應最長處理時間爲30s,若是超過30s,將會掛掉,返回504,以下圖所示:
影響一個HTTP網絡請求的因素主要有兩個:帶寬和延遲。
http的發展也就是在不斷地優化這些方向上的問題。
HTTP1.0最先在網頁中使用是在1996年,那個時候只是使用一些較爲簡單的網頁上和網絡請求上,而HTTP1.1則在1999年纔開始普遍應用於如今的各大瀏覽器網絡請求中,同時HTTP1.1也是當前使用最爲普遍的HTTP協議。 主要區別主要體如今:
雖然 HTTP/1.1 已經優化了不少點,做爲一個目前使用最普遍的協議版本,已經可以知足不少網絡需求,可是隨着網頁變得愈來愈複雜,甚至演變成爲獨立的應用,HTTP/1.1 逐漸暴露出了一些問題:
HTTPS 是以安全爲目標的 HTTP 通道,簡單講是 HTTP 的安全版,即 HTTP 下加入 SSL 層,HTTPS 的安全基礎是 SSL,所以加密的詳細內容就須要 SSL。
2012年google如一聲驚雷提出了SPDY的方案,優化了HTTP1.X的請求延遲,解決了HTTP1.X的安全性,具體以下:
SPDY構成圖:
SPDY位於HTTP之下,TCP和SSL之上,這樣能夠輕鬆兼容老版本的HTTP協議(將HTTP1.x的內容封裝成一種新的frame格式),同時可使用已有的SSL功能。
HTTP2.0能夠說是SPDY的升級版(其實本來也是基於SPDY設計的),可是,HTTP2.0 跟 SPDY 仍有不一樣的地方,以下:
HTTP2.0和SPDY的區別:
HTTP/2 新特性
HTTP/2 採用二進制格式傳輸數據,而非 HTTP 1.x 的文本格式,二進制協議解析起來更高效。 HTTP / 1 的請求和響應報文,都是由起始行,首部和實體正文(可選)組成,各部分之間以文本換行符分隔。HTTP/2 將請求和響應數據分割爲更小的幀,而且它們採用二進制編碼。
接下來咱們介紹幾個重要的概念:
HTTP/2 中,同域名下全部通訊都在單個鏈接上完成,該鏈接能夠承載任意數量的雙向數據流。每一個數據流都以消息的形式發送,而消息又由一個或多個幀組成。多個幀之間能夠亂序發送,根據幀首部的流標識能夠從新組裝。
在 HTTP/2 中引入了多路複用的技術。多路複用很好的解決了瀏覽器限制同一個域名下的請求數量的問題,同時也接更容易實現全速傳輸,畢竟新開一個 TCP 鏈接都須要慢慢提高傳輸速度。
在 HTTP/2 中,有了二進制分幀以後,HTTP /2 再也不依賴 TCP 連接去實現多流並行了,在 HTTP/2中:
這一特性,使性能有了極大提高:
如上圖所示,多路複用的技術能夠只經過一個 TCP 鏈接就能夠傳輸全部的請求數據。
在 HTTP/1 中,咱們使用文本的形式傳輸 header,在 header 攜帶 cookie 的狀況下,可能每次都須要重複傳輸幾百到幾千的字節。
爲了減小這塊的資源消耗並提高性能, HTTP/2對這些首部採起了壓縮策略:
例以下圖中的兩個請求, 請求一發送了全部的頭部字段,第二個請求則只須要發送差別數據,這樣能夠減小冗餘數據,下降開銷
Server Push即服務端能經過push的方式將客戶端須要的內容預先推送過去,也叫「cache push」。
能夠想象如下狀況,某些資源客戶端是必定會請求的,這時就能夠採起服務端 push 的技術,提早給客戶端推送必要的資源,這樣就能夠相對減小一點延遲時間。固然在瀏覽器兼容的狀況下你也可使用 prefetch。
例如服務端能夠主動把JS和CSS文件推送給客戶端,而不須要客戶端解析HTML時再發送這些請求。
服務端能夠主動推送,客戶端也有權利選擇是否接收。若是服務端推送的資源已經被瀏覽器緩存過,瀏覽器能夠經過發送RST_STREAM幀來拒收。主動推送也遵照同源策略,換句話說,服務器不能隨便將第三方資源推送給客戶端,而必須是通過雙方確認才行。
後續更多文章將在個人 github第一時間發佈,歡迎關注。
參考