先說說http1.0
http1.0
HTTP 協議老的標准是HTTP/1.0,為了提高系統的效率,HTTP 1.0規定瀏覽器與服務器只保持短暫的連接,瀏覽器的每次請求都需要與服務器建立一個TCP連接,服務器完成請求處理后立即斷開TCP連接,服務器不跟蹤每個客戶也不記錄過去的請求。但是,這也造成了一些性能上的缺陷,假如一個網頁中包含很多圖片和請求,每次都要斷開重新連接,嚴重影響客戶機和服務器的性能。基於此會發現,http1.0被抱怨最多的就是連接無法復用,和head of line blocking這兩個問題。
連接無法復用會導致每次請求都經歷三次握手和慢啟動。三次握手在高延遲的場景下影響較明顯,慢啟動則對文件類大請求影響較大。
head of line blocking會導致帶寬無法被充分利用,以及后續健康請求被阻塞。
HTTP1.1
一、HTTP 1.1支持持久連接(HTTP/1.1的默認模式使用帶流水線的持久連接),在一個TCP連接上可以傳送多個HTTP請求和響應,減少了建立和關閉連接的消耗和延遲。 二、HTTP 1.1還允許客戶端不用等待上一次請求結果返回,就可以發出下一次請求,但服務器端必須按照接收到客戶端請求的先后順序依次回送響應結果,以保證客戶端能夠區分出每次請求的響應內容,這樣也顯著地減少了整個下載過程所需要的時間。 三、在HTTP 1.1中增加Host請求頭字段。 我們可以在一台WEB服務器上可以在同一個IP地址和端口號上使用不同的主機名來創建多個虛擬WEB站點。 四、HTTP 1.1還提供了與身份認證、狀態管理和Cache緩存等機制相關的請求頭和響應頭。 五、HTTP 1.1支持斷點續傳
在http1.1的相關配置:
在http1.1中默認就是長連接,在請求頭中你會發現如下:
假如不使用長連接,則要如下設置:
Connection:close
斷點續傳配置:
Accept-Ranges : bytes | none
我們常常為圖片等資源設置Accept-Ranges:bytes標頭,以便使客戶端,可以使用斷點續傳功能,當然,這一切的前提是,客戶端之前有緩存部分數據。
Accept-Ranges:bytes=XXXX
表示從XXX開始斷點續傳。
HTTP 1.1狀態代碼及其含義
這里是附加寫的,因為狀態碼是面試中經常提的問題,理解http1.1中的各種狀態碼:
1xx:指示信息--表示請求已接收,繼續處理
100 Continue 初始的請求已經接受,客戶應當繼續發送請求的其余部分。(HTTP 1.1新) 101 Switching Protocols 服務器將遵從客戶的請求轉換到另外一種協議(HTTP 1.1新)
2xx:成功--表示請求已被成功接收、理解、接受
200 OK 一切正常,對GET和POST請求的應答文檔跟在后面。 201 Created 服務器已經創建了文檔,Location頭給出了它的URL。 202 Accepted 已經接受請求,但處理尚未完成。 203 Non-Authoritative Information 文檔已經正常地返回,但一些應答頭可能不正確,因為使用的是文檔的拷貝(HTTP 1.1新)。 204 No Content 沒有新文檔,瀏覽器應該繼續顯示原來的文檔。如果用戶定期地刷新頁面,而Servlet可以確定用戶文檔足夠新,這個狀態代碼是很有用的。 205 Reset Content 沒有新的內容,但瀏覽器應該重置它所顯示的內容。用來強制瀏覽器清除表單輸入內容(HTTP 1.1新)。 206 Partial Content 客戶發送了一個帶有Range頭的GET請求,服務器完成了它(HTTP 1.1新)。
3xx:重定向--要完成請求必須進行更進一步的操作
300 Multiple Choices 客戶請求的文檔可以在多個位置找到,這些位置已經在返回的文檔內列出。如果服務器要提出優先選擇,則應該在Location應答頭指明。 301 Moved Permanently 客戶請求的文檔在其他地方,新的URL在Location頭中給出,瀏覽器應該自動地訪問新的URL。 302 Found 類似於301,但新的URL應該被視為臨時性的替代,而不是永久性的。注意,在HTTP1.0中對應的狀態信息是“Moved Temporatily”。 出現該狀態代碼時,瀏覽器能夠自動訪問新的URL,因此它是一個很有用的狀態代碼。 注意這個狀態代碼有時候可以和301替換使用。例如,如果瀏覽器錯誤地請求http://host/~user(缺少了后面的斜杠),有的服務器返回301,有的則返回302。 嚴格地說,我們只能假定只有當原來的請求是GET時瀏覽器才會自動重定向。請參見307。 303 See Other 類似於301/302,不同之處在於,如果原來的請求是POST,Location頭指定的重定向目標文檔應該通過GET提取(HTTP 1.1新)。 304 Not Modified 客戶端有緩沖的文檔並發出了一個條件性的請求(一般是提供If-Modified-Since頭表示客戶只想比指定日期更新的文檔)。服務器告訴客戶,原來緩沖的文檔還可以繼續使用。 305 Use Proxy 客戶請求的文檔應該通過Location頭所指明的代理服務器提取(HTTP 1.1新)。 307 Temporary Redirect 和302(Found)相同。許多瀏覽器會錯誤地響應302應答進行重定向,即使原來的請求是POST,即使它實際上只能在POST請求的應答是303時 才能重定向。由於這個原因,HTTP 1.1新增了307,以便更加清除地區分幾個狀態代碼:當出現303應答時,瀏覽器可以跟隨重定向的GET和POST請求;如果是307應答,則瀏覽器只能跟隨對GET請求的重定向。(HTTP 1.1新)
4xx:客戶端錯誤--請求有語法錯誤或請求無法實現
400 Bad Request 請求出現語法錯誤。 401 Unauthorized 客戶試圖未經授權訪問受密碼保護的頁面。應答中會包含一個WWW-Authenticate頭,瀏覽器據此顯示用戶名字/密碼對話框,然后在填寫合適的Authorization頭后再次發出請求。 403 Forbidden 資源不可用。服務器理解客戶的請求,但拒絕處理它。通常由於服務器上文件或目錄的權限設置導致。 404 Not Found 無法找到指定位置的資源。這也是一個常用的應答。 405 Method Not Allowed 請求方法(GET、POST、HEAD、DELETE、PUT、TRACE等)對指定的資源不適用。(HTTP 1.1新) 406 Not Acceptable 指定的資源已經找到,但它的MIME類型和客戶在Accpet頭中所指定的不兼容(HTTP 1.1新)。 407 Proxy Authentication Required 類似於401,表示客戶必須先經過代理服務器的授權。(HTTP 1.1新) 408 Request Timeout 在服務器許可的等待時間內,客戶一直沒有發出任何請求。客戶可以在以后重復同一請求。(HTTP 1.1新) 409 Conflict 通常和PUT請求有關。由於請求和資源的當前狀態相沖突,因此請求不能成功。(HTTP 1.1新) 410 Gone 所請求的文檔已經不再可用,而且服務器不知道應該重定向到哪一個地址。它和404的不同在於,返回407表示文檔永久地離開了指定的位置,而404表示由於未知的原因文檔不可用。(HTTP 1.1新) 411 Length Required 服務器不能處理請求,除非客戶發送一個Content-Length頭。(HTTP 1.1新) 412 Precondition Failed 請求頭中指定的一些前提條件失敗(HTTP 1.1新)。 413 Request Entity Too Large 目標文檔的大小超過服務器當前願意處理的大小。如果服務器認為自己能夠稍后再處理該請求,則應該提供一個Retry-After頭(HTTP 1.1新)。 414 Request URI Too Long URI太長(HTTP 1.1新)。 416 Requested Range Not Satisfiable 服務器不能滿足客戶在請求中指定的Range頭。(HTTP 1.1新)
5xx:服務器端錯誤--服務器未能實現合法的請求
500 Internal Server Error 服務器遇到了意料不到的情況,不能完成客戶的請求。 501 Not Implemented 服務器不支持實現請求所需要的功能。例如,客戶發出了一個服務器不支持的PUT請求。 502 Bad Gateway 服務器作為網關或者代理時,為了完成請求訪問下一個服務器,但該服務器返回了非法的應答。 503 Service Unavailable 服務器由於維護或者負載過重未能應答。例如,Servlet可能在數據庫連接池已滿的情況下返回503。服務器返回503時可以提供一個Retry-After頭。 504 Gateway Timeout 由作為代理或網關的服務器使用,表示不能及時地從遠程服務器獲得應答。(HTTP 1.1新) 505 HTTP Version Not Supported 服務器不支持請求中所指明的HTTP版本。(HTTP 1.1新)
HTTP2.0
http2.0新特性如下:
多路復用 (Multiplexing)
多路復用允許同時通過單一的 HTTP/2 連接發起多重的請求-響應消息。在 HTTP/1.1 協議中瀏覽器客戶端在同一時間,針對同一域名下的請求有一定數量限制。超過限制數目的請求會被阻塞。
而 HTTP/2 的多路復用(Multiplexing) 則允許同時通過單一的 HTTP/2 連接發起多重的請求-響應消息。因此 HTTP/2 可以很容易的去實現多流並行而不用依賴建立多個 TCP 連接,HTTP/2 把 HTTP 協議通信的基本單位縮小為一個一個的幀,這些幀對應着邏輯流中的消息。並行地在同一個 TCP 連接上雙向交換消息。
二進制分幀
HTTP/2在 應用層(HTTP/2)和傳輸層(TCP or UDP)之間增加一個二進制分幀層。在不改動 HTTP/1.x 的語義、方法、狀態碼、URI 以及首部字段的情況下, 解決了HTTP1.1 的性能限制,改進傳輸性能,實現低延遲和高吞吐量。
首部壓縮(Header Compression)
HTTP/1.1並不支持 HTTP 首部壓縮,為此 SPDY 和 HTTP/2 應運而生, SPDY 使用的是通用的DEFLATE 算法,而 HTTP/2 則使用了專門為首部壓縮而設計的 HPACK 算法。
服務端推送(Server Push)
服務端推送是一種在客戶端請求之前發送數據的機制。在 HTTP/2 中,服務器可以對客戶端的一個請求發送多個響應。 Server Push 讓 HTTP1.x 時代使用內嵌資源的優化手段變得沒有意義; 如果一個請求是由你的主頁發起的,服務器很可能會響應主頁內容、logo 以及樣式表,因為它知道客戶端會用到這些東西。這相當於在一個 HTML 文檔內集合了所有的資源。 與之相比,服務器推送還有一個很大的優勢:可以緩存!也讓在遵循同源的情況下,不同頁面之間可以共享緩存資源成為可能。
HTTPS
已經講了http1.0,http1.1和http2.0了,這里不差https了,再寫一下https
HTTPS都是用的TLS協議,但是由於SSL出現的時間比較早【SSL(Secure Sockets Layer)協議用於對HTTP協議傳輸的數據進行加密】,並且依舊被現在瀏覽器所支持,因此SSL依然是HTTPS的代名詞。
HTTPS在傳輸數據之前需要客戶端(瀏覽器)與服務端(網站)之間進行一次握手,在握手過程中將確立雙方加密傳輸數據的密碼信息。TLS/SSL協議不僅僅是一套加密傳輸的協議,TLS/SSL中使用了非對稱加密,對稱加密以及HASH算法。握手過程的簡單描述如下:
1.瀏覽器將自己支持的一套加密規則發送給網站。 2.網站從中選出一組加密算法與HASH算法,並將自己的身份信息以證書的形式發回給瀏覽器。證書里面包含了網站地址,加密公鑰,以及證書的頒發機構等信息。 3.獲得網站證書之后瀏覽器要做以下工作: a) 驗證證書的合法性(頒發證書的機構是否合法,證書中包含的網站地址是否與正在訪問的地址一致等),如果證書受信任,則瀏覽器欄里面會顯示一個小鎖頭,否則會給出證書不受信的提示。 b) 如果證書受信任,或者是用戶接受了不受信的證書,瀏覽器會生成一串隨機數的密碼,並用證書中提供的公鑰加密。 c) 使用約定好的HASH計算握手消息,並使用生成的隨機數對消息進行加密,最后將之前生成的所有信息發送給網站。 4.網站接收瀏覽器發來的數據之后要做以下的操作: a) 使用自己的私鑰將信息解密取出密碼,使用密碼解密瀏覽器發來的握手消息,並驗證HASH是否與瀏覽器發來的一致。 b) 使用密碼加密一段握手消息,發送給瀏覽器。 5.瀏覽器解密並計算握手消息的HASH,如果與服務端發來的HASH一致,此時握手過程結束,之后所有的通信數據將由之前瀏覽器生成的隨機密碼並利用對稱加密算法進行加密。
TLS握手過程中如果有任何錯誤,都會使加密連接斷開,從而阻止了隱私信息的傳輸。正是由於HTTPS非常的安全,攻擊者無法從中找到下手的地方,於是更多的是采用了假證書的手法來欺騙客戶端,從而獲取明文的信息。默認HTTP的端口號為80,HTTPS的端口號為443。
長連接,短連接
普及了這么多知識之后,再說長連接和短連接,大家應該很清楚了吧,長連接就是http1.1支持的鏈接。
長連接過程如下:
連接->傳輸數據->保持連接 -> 傳輸數據-> 。。。 ->關閉連接。
短連接如下:
連接->傳輸數據->關閉連接
WebSocket
關於websocket,我之前應該有文章介紹過:具體請看文章:http://www.haorooms.com/post/html5_websocket
關於websocket的一些操作,這篇文章就不詳細闡述了。更多請看
服務器發送事件sse
這個是我之前寫的一篇文章,主要是服務器主動發送。歡迎去看看!
websocket和輪詢及長輪詢區別
輪詢如下:
客戶端:啦啦啦,有沒有新信息(Request) 服務端:沒有(Response) 客戶端:啦啦啦,有沒有新信息(Request) 服務端:沒有。。(Response) 客戶端:啦啦啦,有沒有新信息(Request) 服務端:你好煩啊,沒有啊。。(Response) 客戶端:啦啦啦,有沒有新消息(Request) 服務端:好啦好啦,有啦給你。(Response) 客戶端:啦啦啦,有沒有新消息(Request) 服務端:。。。。。沒。。。。沒。。。沒有(Response) ---- loop
長輪詢如下:
客戶端:啦啦啦,有沒有新信息,沒有的話就等有了才返回給我吧(Request) 服務端:額。。 等待到有消息的時候。。來 給你(Response) 客戶端:啦啦啦,有沒有新信息,沒有的話就等有了才返回給我吧(Request) -loop
websocket如下:
websocket解決了HTTP的這幾個難題。 首先,被動性,當服務器完成協議升級后(HTTP->Websocket),服務端就可以主動推送信息給客戶端啦。
所以上面的情景可以做如下修改。
客戶端:啦啦啦,我要建立Websocket協議,需要的服務:chat,Websocket協議版本:17(HTTP Request) 服務端:ok,確認,已升級為Websocket協議(HTTP Protocols Switched) 客戶端:麻煩你有信息的時候推送給我噢。。 服務端:ok,有的時候會告訴你的。 服務端:balabalabalabala 服務端:balabalabalabala 服務端:哈哈哈哈哈啊哈哈哈哈 服務端:笑死我了哈哈哈哈哈哈哈