深刻理解 HTTP 協議

簡介

HTTP協議(超文本傳輸協議HyperText Transfer Protocol),它是基於TCP協議的應用層傳輸協議,簡單來講就是客戶端和服務端進行數據傳輸的一種規則。html

注意:客戶端與服務器的角色不是固定的,一端充當客戶端,也可能在某次請求中充當服務器。這取決與請求的發起端。HTTP協議屬於應用層,創建在傳輸層協議TCP之上。客戶端經過與服務器創建TCP鏈接,以後發送HTTP請求與接收HTTP響應都是經過訪問Socket接口來調用TCP協議實現。web

HTTP 是一種無狀態 (stateless) 協議, HTTP協議自己不會對發送過的請求和相應的通訊狀態進行持久化處理。這樣作的目的是爲了保持HTTP協議的簡單性,從而可以快速處理大量的事務, 提升效率。算法

然而,在許多應用場景中,咱們須要保持用戶登陸的狀態或記錄用戶購物車中的商品。因爲HTTP是無狀態協議,因此必須引入一些技術來記錄管理狀態,例如Cookie編程

正文

HTTP URL

HTTP URL 包含了用於查找某個資源的詳細信息, 格式以下:後端

http://host[":"port][abs_path]
複製代碼

HTTP請求

下圖是在網上找的一張圖,以爲能很好的表達HTTP請求的所發送的數據格式。瀏覽器

由上圖能夠看到,http請求由請求行,消息報頭,請求正文三部分構成。緩存

HTTP請求狀態行

請求行由請求Method, URL 字段和HTTP Version三部分構成, 總的來講請求行就是定義了本次請求的請求方式, 請求的地址, 以及所遵循的HTTP協議版本例如:安全

GET /example.html HTTP/1.1 (CRLF)
複製代碼

HTTP協議的方法有:bash

  • GET: 請求獲取Request-URI所標識的資源
  • POST: 在Request-URI所標識的資源後增長新的數據
  • HEAD: 請求獲取由Request-URI所標識的資源的響應消息報頭
  • PUT: 請求服務器存儲或修改一個資源,並用Request-URI做爲其標識
  • DELETE: 請求服務器刪除Request-URI所標識的資源
  • TRACE: 請求服務器回送收到的請求信息,主要用於測試或診斷
  • CONNECT: 保留未來使用
  • OPTIONS: 請求查詢服務器的性能,或者查詢與資源相關的選項和需求

HTTP請求頭

消息報頭由一系列的鍵值對組成,容許客戶端向服務器端發送一些附加信息或者客戶端自身的信息,主要包括:服務器

Header 解釋 示例
Accept 指定客戶端可以接收的內容類型 Accept: text/plain, text/html
Accept-Charset 瀏覽器能夠接受的字符編碼集 Accept-Charset: iso-8859-5,utf-8
Accept-Encoding 指定瀏覽器能夠支持的web服務器返回內容壓縮編碼類型 Accept-Encoding: compress, gzip
Accept-Language 瀏覽器可接受的語言 Accept-Language: en,zh
Accept-Ranges 能夠請求網頁實體的一個或者多個子範圍字段 Accept-Ranges: bytes
Authorization HTTP受權的受權證書類型 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Cache-Control 指定請求和響應遵循的緩存機制 Cache-Control: no-cache
Connection 表示是否須要持久鏈接(HTTP 1.1默認進行持久鏈接) Connection: close
Cookie HTTP請求發送時,會把保存在該請求域名下的全部cookie值一塊兒發送給web服務器 Cookie: $Version=1; Skin=new;
Content-Length 請求的內容長度 Content-Length: 348
Content-Type 請求的與實體對應的MIME信息 Content-Type: application/x-www-form-urlencoded
Date 請求發送的日期和時間 Date: Tue, 15 Nov 2010 08:12:31 GMT
Expect 請求的特定的服務器行爲 Expect: 100-continue
From 發出請求的用戶的Email From: user@email.com
Host 指定請求的服務器的域名和端口號 Host: www.zcmhi.com
If-Match 只有請求內容與實體相匹配纔有效 If-Match: 「737060cd8c284d8af7ad3082f209582d」
If-Modified-Since 若是請求的部分在指定時間以後被修改則請求成功,未被修改則返回304代碼 If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT
If-None-Match 若是內容未改變返回304代碼,參數爲服務器先前發送的Etag,與服務器迴應的Etag比較判斷是否改變 If-None-Match: 「737060cd8c284d8af7ad3082f209582d」
If-Range 若是實體未改變,服務器發送客戶端丟失的部分,不然發送整個實體。參數也爲Etag If-Range: 「737060cd8c284d8af7ad3082f209582d」
If-Unmodified-Since 只在實體在指定時間以後未被修改才請求成功 If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT
Max-Forwards 限制信息經過代理和網關傳送的時間 Max-Forwards: 10
Pragma 用來包含實現特定的指令 Pragma: no-cache
Proxy-Authorization 鏈接到代理的受權證書 Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Range 只請求實體的一部分,指定範圍 Range: bytes=500-999
Referer 先前網頁的地址,當前請求網頁緊隨其後, 即來路 Referer: www.zcmhi.com/archives/71…
TE 客戶端願意接受的傳輸編碼,並通知服務器接受接受尾加頭信息 TE: trailers,deflate;q=0.5
Upgrade 向服務器指定某種傳輸協議以便服務器進行轉換(若是支持) Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
User-Agent User-Agent的內容包含發出請求的用戶信息 User-Agent: Mozilla/5.0 (Linux; X11)
Via 通知中間網關或代理服務器地址,通訊協議 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
Warning 關於消息實體的警告信息 Warn: 199 Miscellaneous warning

HTTP請求正文

只有在發送POST請求時纔會有請求正文,GET方法並無請求正文。

HTTP請求報文

HTTP響應

與HTTP請求相似,先上一張圖:

HTTP響應也由三部分組成,包括狀態行,消息報頭,響應正文。

HTTP響應狀態行

狀態行也由三部分組成,包括HTTP協議的版本,狀態碼,以及對狀態碼的文本描述。例如:

HTTP/1.1 200 OK (CRLF)
複製代碼

HTTP響應狀態碼

狀態代碼有三位數字組成,第一個數字定義了響應的類別,且有五種可能取值:

  • 1xx指示信息 - 表示請求已接收,繼續處理
  • 2xx成功 - 表示請求已被成功接收、理解、接受
  • 3xx重定向 - 要完成請求必須進行更進一步的操做
  • 4xx客戶端錯誤 - 請求有語法錯誤或請求沒法實現
  • 5xx服務器端錯誤 - 服務器未能實現合法的請求

常見狀態代碼、狀態描述、說明:

  • 200OK - 客戶端請求成功
  • 400Bad Request - 客戶端請求有語法錯誤,不能被服務器所理解
  • 401Unauthorized - 請求未經受權,這個狀態代碼必須和WWW-Authenticate報頭域一塊兒使用
  • 403Forbidden - 服務器收到請求,可是拒絕提供服務
  • 404Not Found - 請求資源不存在,eg:輸入了錯誤的URL
  • 500Internal Server Error - 服務器發生不可預期的錯誤
  • 503Server Unavailable - 服務器當前不能處理客戶端的請求,一段時間後,可能恢復正常

HTTP響應狀態碼說明

StatusCode StatusCode語義 中文描述
100 Continue 繼續。客戶端應繼續其請求
101 Switching Protocols 切換協議。服務器根據客戶端的請求切換協議。只能切換到更高級的協議,例如,切換到HTTP的新版本協議
200 OK 請求成功。通常用於GET與POST請求
201 Created 已建立。成功請求並建立了新的資源
202 Accepted 已接受。已經接受請求,但未處理完成
203 Non-Authoritative Information 非受權信息。請求成功。但返回的meta信息不在原始的服務器,而是一個副本
204 No Content 無內容。服務器成功處理,但未返回內容。在未更新網頁的狀況下,可確保瀏覽器繼續顯示當前文檔
205 Reset Content 重置內容。服務器處理成功,用戶終端(例如:瀏覽器)應重置文檔視圖。可經過此返回碼清除瀏覽器的表單域
206 Partial Content 部份內容。服務器成功處理了部分GET請求
300 Multiple Choices 多種選擇。請求的資源可包括多個位置,相應可返回一個資源特徵與地址的列表用於用戶終端(例如:瀏覽器)選擇
301 Moved Permanently 永久移動。請求的資源已被永久的移動到新URI,返回信息會包括新的URI,瀏覽器會自動定向到新URI。從此任何新的請求都應使用新的URI代替
302 Found 臨時移動。 與301相似。但資源只是臨時被移動。客戶端應繼續使用原有URI
303 See Other 查看其它地址。與301相似。使用GET和POST請求查看
304 Not Modified 未修改。所請求的資源未修改,服務器返回此狀態碼時,不會返回任何資源。客戶端一般會緩存訪問過的資源,經過提供一個頭信息指出客戶端但願只返回在指定日期以後修改的資源
305 Use Proxy 使用代理。所請求的資源必須經過代理訪問
306 Unused 已經被廢棄的HTTP狀態碼
307 Temporary Redirect 臨時重定向。與302相似。使用GET請求重定向
400 Bad Request 客戶端請求的語法錯誤,服務器沒法理解
401 Unauthorized 請求要求用戶的身份認證
402 Payment Required 保留,未來使用
403 Forbidden 服務器理解請求客戶端的請求,可是拒絕執行此請求
404 Not Found 服務器沒法根據客戶端的請求找到資源(網頁)。經過此代碼,網站設計人員可設置"您所請求的資源沒法找到"的個性頁面
405 Method Not Allowed 客戶端請求中的方法被禁止
406 Not Acceptable 服務器沒法根據客戶端請求的內容特性完成請求
407 Proxy Authentication Required 請求要求代理的身份認證,與401相似,但請求者應當使用代理進行受權
408 Request Time-out 服務器等待客戶端發送的請求時間過長,超時
409 Conflict 服務器完成客戶端的PUT請求是可能返回此代碼,服務器處理請求時發生了衝突
410 Gone 客戶端請求的資源已經不存在。410不一樣於404,若是資源之前有如今被永久刪除了可以使用410代碼,網站設計人員可經過301代碼指定資源的新位置
411 Length Required 服務器沒法處理客戶端發送的不帶Content-Length的請求信息
412 Precondition Failed 客戶端請求信息的先決條件錯誤
413 Request Entity Too Large 因爲請求的實體過大,服務器沒法處理,所以拒絕請求。爲防止客戶端的連續請求,服務器可能會關閉鏈接。若是隻是服務器暫時沒法處理,則會包含一個Retry-After的響應信息
414 Request-URI Too Larg 請求的URI過長(URI一般爲網址),服務器沒法處理
415 Unsupported Media Type 服務器沒法處理請求附帶的媒體格式
416 Requested range not satisfiable 客戶端請求的範圍無效
417 Expectation Failed 服務器沒法知足Expect的請求頭信息
500 Internal Server Error 服務器內部錯誤,沒法完成請求
501 Not Implemented 服務器不支持請求的功能,沒法完成請求
502 Bad Gateway 充當網關或代理的服務器,從遠端服務器接收到了一個無效的請求
503 Service Unavailable 因爲超載或系統維護,服務器暫時的沒法處理客戶端的請求。延時的長度可包含在服務器的Retry-After頭信息中
504 Gateway Time-out 充當網關或代理的服務器,未及時從遠端服務器獲取請求
505 HTTP Version not supported 服務器不支持請求的HTTP協議的版本,沒法完成處理

HTTP響應報文

HTTP協議詳解

HTTP的五大特色

  1. 支持客戶/服務器模式。
  2. 簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法經常使用的有GETHEADPOST。每種方法規定了客戶與服務器聯繫的類型不一樣。因爲HTTP協議簡單,使得HTTP服務器的程序規模小,於是通訊速度很快。
  3. 靈活:HTTP容許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
  4. 無鏈接:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。早期這麼作的緣由是請求資源少,追求快。後來經過Connection: Keep-Alive實現長鏈接
  5. 無狀態HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外一方面,在服務器不須要先前信息時它的應答就較快。

非持久鏈接和持久鏈接

在實際的應用中,客戶端每每會發出一系列請求,接着服務器端對每一個請求進行響應。對於這些請求|響應,若是每次都通過一個單獨的TCP鏈接發送,稱爲非持久鏈接。反之,若是每次都通過相同的TCP鏈接進行發送,稱爲持久鏈接

非持久鏈接在每次請求|響應以後都要斷開鏈接,下次再創建新的TCP鏈接,這樣就形成了大量的通訊開銷。例如前面提到的往返時間(RTT) 就是在創建TCP鏈接的過程當中的代價。

非持久鏈接給服務器帶來了沉重的負擔,每臺服務器可能同時面對數以百計甚至更多的請求。持久鏈接就是爲了解決這些問題,其特色是一直保持TCP鏈接狀態,直到遇到明確的中斷要求以後再中斷鏈接。持久鏈接減小了通訊開銷,節省了通訊量。

HTTP和HTTPS

HTTP的不足

  • 通訊使用明文(不加密),內容可能會被竊聽
  • 不驗證通訊方的身份,所以有可能遭遇假裝
  • 沒法證實報文的完整性,因此有可能已遭篡改

HTTPS介紹

HTTP 協議中沒有加密機制,但能夠通 過和 SSL(Secure Socket Layer, 安全套接層 )或 TLS(Transport Layer Security, 安全層傳輸協議)的組合使用,加密 HTTP 的通訊內容。屬於通訊加密,即在整個通訊線路中加密。

HTTP + 加密 + 認證 + 完整性保護 = HTTPS(HTTP Secure )
複製代碼

HTTP和HTTPS對比

HTTPS 採用共享密鑰加密(對稱)和公開密鑰加密(非對稱)二者並用的混合加密機制。若密鑰可以實現安全交換,那麼有可能會考慮僅使用公開密鑰加密來通訊。可是公開密鑰加密與共享密鑰加密相比,其處理速度要慢。

因此應充分利用二者各自的優點, 將多種方法組合起來用於通訊。 在交換密鑰階段使用公開密鑰加密方式,以後的創建通訊交換報文階段 則使用共享密鑰加密方式。

混合加密方式

HTTPS握手過程的簡單描述以下:

`HTTPS`握手過程

  1. 瀏覽器將本身支持的一套加密規則發送給網站。

    服務器得到瀏覽器公鑰
    複製代碼
  2. 網站從中選出一組加密算法與HASH算法,並將本身的身份信息以證書的形式發回給瀏覽器。證書裏面包含了網站地址,加密公鑰,以及證書的頒發機構等信息。

    瀏覽器得到服務器公鑰
    複製代碼
  3. 得到網站證書以後瀏覽器要作如下工做:

    (a). 驗證證書的合法性(頒發證書的機構是否合法,證書中包含的網站地址是否與正在訪問的地址一致等),若是證書受信任,則瀏覽器欄裏面會顯示一個小鎖頭,不然會給出證書不受信的提示。

    (b). 若是證書受信任,或者是用戶接受了不受信的證書,瀏覽器會生成一串隨機數的密碼(接下來通訊的密鑰),並用證書中提供的公鑰加密(共享密鑰加密)。

    (c) 使用約定好的HASH計算握手消息,並使用生成的隨機數對消息進行加密,最後將以前生成的全部信息發送給網站。

    瀏覽器驗證 -> 隨機密碼
      服務器的公鑰加密 -> 通訊的密鑰
      通訊的密鑰 -> 服務器
    複製代碼
  4. 網站接收瀏覽器發來的數據以後要作如下的操做:

    (a). 使用本身的私鑰將信息解密取出密碼,使用密碼解密瀏覽器發來的握手消息,並驗證HASH是否與瀏覽器發來的一致。

    (b). 使用密碼加密一段握手消息,發送給瀏覽器。

    服務器用本身的私鑰解出隨機密碼 -> 用密碼解密握手消息(共享密鑰通訊)-> 驗證HASH與瀏覽器是否一致(驗證瀏覽器)
    複製代碼

HTTPS的不足

  • 加密解密過程複雜,致使訪問速度慢
  • 加密須要認向證機構付費
  • 整個頁面的請求都要使用HTTPS

歡迎關注技術公衆號: 零壹技術棧

零壹技術棧

本賬號將持續分享後端技術乾貨,包括虛擬機基礎,多線程編程,高性能框架,異步、緩存和消息中間件,分佈式和微服務,架構學習和進階等學習資料和文章。

相關文章
相關標籤/搜索