1. 程式人生 > >HTTP協議(超文字傳送協議)

HTTP協議(超文字傳送協議)

一、概念

HTTP–Hyper Text Transfer Protocol,超文字傳輸協議,是一種建立在TCP上的無狀態連線,整個基本的工作流程是客戶端傳送一個HTTP請求,說明客戶端想要訪問的資源和請求的動作,服務端收到請求之後,服務端開始處理請求,並根據請求做出相應的動作訪問伺服器資源,最後通過傳送HTTP響應把結果返回給客戶端。
其中一個請求的開始到一個響應的結束稱為事務,當一個事物結束後還會在服務端新增一條日誌條目。

  • TCP/IP協議
    因為HTTP協議是屬於TCP/IP協議簇的,所以先簡單複習一下與HTTP相關的TCP/IP知識。
    TCP/IP是一個協議簇,是由許多協議組成的。TCP/IP四層模型。按照層次從上至下分為四層:應用層,傳輸層,網路層,資料鏈路層。
    參考模型
  1. 應用層 :
    應用層決定了向用戶提供應用服務時通訊的活動。TCP/IP協議族內預存了各類通用的應用服務。比如,FTP(File Transfer Protocol,檔案傳輸協議)和DNS(Domain Name System,域名系統)服務就是其中兩類。HTTP協議也處於該層。

  2. 傳輸層 :
    傳輸層對上層應用層,提供處於網路連線中的兩臺計算機之間的資料傳輸。在傳輸層有兩個性質不同的協議:TCP(Transmission ControlProtocol,傳輸控制協議)和UDP(User Data Protocol,使用者資料報協議)。

  3. 網路層 :
    網路層用來處理在網路上流動的資料包。資料包是網路傳輸的最小資料單位。該層規定了通過怎樣的路徑(所謂的傳輸路線)到達對方計算機,並把資料包傳送給對方。與對方計算機之間通過多臺計算機或網路裝置進行傳輸時,網路層所起的作用就是在眾多的選項內選擇一條傳輸路線。

  4. 鏈路層(又名資料鏈路層,網路介面層) :
    用來處理連線網路的硬體部分。包括控制作業系統、硬體的裝置驅動、NIC(Network Interface Card,網路介面卡,即網絡卡),及光纖等物理可見部分(還包括聯結器等一切傳輸媒介)。硬體上的範疇均在鏈路層的作用範圍之內。
    HTTP請求訪問過程

  • URI/URL
    統一資源識別符號(英語:Uniform Resource Identifier,或URI)是一個用於標識某一網際網路資源名稱的字串。 該種標識允許使用者對網路中(一般指全球資訊網)的資源通過特定的協議進行互動操作。URI的最常見的形式是統一資源定位符(URL),經常指定為非正式的網址。更罕見的用法是統一資源名稱(URN),其目的是通過提供一種途徑。用於在特定的名字空間資源的標識,以補充網址。統一資源名(URN)如同一個人的名稱,而統一資源定位符(URL)代表一個人的住址。換言之,URN定義某事物的身份,而URL提供查詢該事物的方法。

URI格式
URI格式

  1. 使用 http: 或 https: 等協議方案名獲取訪問資源時要指定協議型別。不區分字母大小寫, 最後附一個冒號(:)。也可使用 data: 或 javascript:這類指定資料或指令碼程式的方案名。
  2. 登入資訊(認證):指定使用者名稱和密碼作為從伺服器端獲取資源時必要的登入資訊(身份認證)。此項是可選項。
  3. 伺服器地址: 使用絕對 URI 必須指定待訪問的伺服器地址。地址可以是類似hackr.jp 這種 DNS 可解析的名稱,或是 192.168.1.1 這類 IPv4 地址名,還可以是 [0:0:0:0:0:0:0:1] 這樣用方括號括起來的 IPv6 地址名。
  4. 伺服器埠號:指定伺服器連線的網路埠號。此項也是可選項,若使用者省略則自動使用預設埠號。
  5. 帶層次的檔案路徑:指定伺服器上的檔案路徑來定位特指的資源。這與 UNIX 系統的檔案目錄結構相似。
  6. 查詢字串:針對已指定的檔案路徑內的資源,可以使用查詢字串傳入任意引數。此項可選。
  7. 片段識別符號:使用片段識別符號通常可標記出已獲取資源中的子資源(文件內的某個位置)。但在 RFC 中並沒有明確規定其使用方法。該項也為可選項。
  • HTTP的基本工作方式
    簡易請求
    請求訪問文字或影象等資源的一端稱為客戶端, 而提供資源響應的一端稱為伺服器端。
    無狀態協議:即客戶端向伺服器端傳送處請求時,伺服器並不會儲存有關客戶端和請求的任何狀態資訊。每次的請求和響應都是獨立的。

二、HTTP請求

  • HTTP請求由狀態行、請求頭、請求正文三部分組成:
    1)狀態行:包括請求方式Method、資源路徑URL、協議版本Version;
    2)請求頭:包括一些訪問的域名、使用者代理、Cookie等資訊;
    3)請求正文:就是HTTP請求的資料。
    備註:請求方式Method一般有GET、POST、PUT、DELETE,含義分別是獲取、修改、上傳、刪除,其中GET方式僅僅為獲取伺服器資源,方式較為簡單,因此在請求方式為GET的HTTP請求資料中,請求正文部分可以省略,直接將想要獲取的資源新增到URL中。

  • 下圖所示就是GET的請求,沒有請求正文。詳細的說明在下邊。
    get
    現在大多數協議版本為http/1.1
    下圖所示為POST請求的格式,有狀態行、請求頭、請求正文三部分。
    post

三、HTTP響應

  • HTTP響應由三部分組成:狀態行、響應頭、響應正文;
    1)狀態行:包括協議版本Version、狀態碼Status Code、迴應短語;
    2)響應頭:包括搭建伺服器的軟體,傳送響應的時間,迴應資料的格式等資訊;
    3)響應正文:就是響應的具體資料。
    備註:我們主要關心並且能夠在客戶端瀏覽器看得到的是三位數的狀態碼,不同的狀態碼代表不同的含義。
    狀態碼

  • 具體HTTP響應例項:
    響應例項

  • 常見狀態碼的含義

200—OK/請求已經正常處理完畢
301—/請求永久重定向
302—/請求臨時重定向
304—/請求被重定向到客戶端本地快取
400—/客戶端請求存在語法錯誤
401—/客戶端請求沒有經過授權
403—/客戶端的請求被伺服器拒絕,一般為客戶端沒有訪問許可權
404—/客戶端請求的URL在服務端不存在
500—/服務端永久錯誤
503—/服務端發生臨時錯誤

四、HTTP報文

用於 HTTP 協議互動的資訊被稱為 HTTP 報文。 請求端(客戶端) 的HTTP 報文叫做請求報文, 響應端(伺服器端) 的叫做響應報文。HTTP 報文字身是由多行(用 CR+LF 作換行符) 資料構成的字串文字。

4.1 報文結構

報文結構
HTTP 報文大致可分為報文首部和報文主體兩塊。 兩者由最初出現的空行(CR+LF) 來劃分。 通常, 並不一定要有報文主體。
HTTP請求頭提供了關於請求,響應或者其他的傳送實體的資訊。HTTP的頭資訊包括通用頭、請求頭、響應頭和實體頭四個部分。每個頭域由一個域名,冒號(:)和域值三部分組成。

通用頭標:即可用於請求,也可用於響應,是作為一個整體而不是特定資源與事務相關聯。
請求頭標:允許客戶端傳遞關於自身的資訊和希望的響應形式。
響應頭標:伺服器和於傳遞自身資訊的響應。
實體頭標:定義被傳送資源的資訊。即可用於請求,也可用於響應。

4.2 請求報文

請求報文
請求報文的起始由請求行構成(有些資料稱為狀態行,名字不一樣而已,都是指的一個東西),由Method、URL、Version三個欄位組成,注意每個欄位之間都有一個空格。

  • 請求行
    1、其中Method欄位有不同的值:
    Method
    2、URL欄位表示伺服器的資源目錄定位;
    3、Version欄位表示使用的http協議版本;

  • 首部欄位
    首部部分由多個請求頭(也叫首部行)構成,那些首部欄位名有如下,不全:
    Accept 指定客戶端能夠接收的內容格式型別
    Accept-Language 指定客戶端能夠接受的語言型別
    Accept-Ecoding 指定客戶端能夠接受的編碼型別
    User-Agent 使用者代理,向伺服器說明自己的作業系統、瀏覽器等資訊
    Connection 是否開啟持久連線(keepalive)
    Host 伺服器域名

  • 實體主體:主體部分就是報文的具體資料

  • 例項
    例項

4.3 響應報文

響應報文
響應報文的起始由狀態行構成,用來說明伺服器做了什麼,由Version、Status-Code、Phrase三個欄位組成,同樣的每個欄位之間留有空格;

  • 請求行
    1、Version欄位表示使用的http協議版本;
    2、Status-Code 狀態碼,上邊已經說明;
    3、Phrase狀態短語;
  • 首部欄位
    首部由多個響應頭(也叫首部行)組成, 首部欄位名如下,不全:
    Server 伺服器軟體名,Apache/Nginx
    Date 伺服器發出響應報文的時間
    Last-Modified 請求資源的最後的修改時間
  • 主體部分是響應報文的具體資料。

五、HTTP的Cookie 和 Session

5.1 Cookie

1. 基本概念

因為HTTP協議是無狀態的,對於一個瀏覽器發出的多次請求,Web伺服器無法區分是不是來源於同一個瀏覽器。所以,需要額外的資料用於維護會話。 Cookie 正是這樣的一段隨HTTP請求一起被傳遞的額外資料。 Cookie 是一小段文字資訊,伴隨著使用者請求和頁面在 Web 伺服器和瀏覽器之間傳遞。Cookie 包含每次使用者訪問站點時 Web 應用程式都可以讀取的資訊。
Cookie能做什麼? Cookie只是一段文字,所以它只能儲存字串。而且瀏覽器對它有大小限制以及它會隨著每次請求被髮送到伺服器,所以應該保證它不要太大。
備註:大多數瀏覽器支援最大為 4096 位元組的 Cookie。由於這限制了 Cookie 的大小,最好用 Cookie 來儲存少量資料,或者儲存使用者 ID 之類的識別符號。使用者 ID隨後便可用於標識使用者,以及從資料庫或其他資料來源中讀取使用者資訊。 瀏覽器還限制站點可以在使用者計算機上儲存的 Cookie的數量。大多數瀏覽器只允許每個站點儲存 20 個Cookie ;如果試圖儲存更多 Cookie,則最舊的 Cookie便會被丟棄。有些瀏覽器還會對它們將接受的來自所有站點的 Cookie 總數作出絕對限制,通常為 300 個。

2. 屬性

屬性

set-cookie欄位
#### 3. 工作機制 Cookie的工作機制是使用者識別及狀態管理。Web網站為了管理使用者的狀態會通過Web瀏覽器,把一些資料臨時寫入使用者的計算機內,接著使用者訪問該Web網站的時候,可通過通訊方式取回之前存的Cookie。 Cookie 會根據從伺服器端傳送的響應報文內的一個叫做 **Set-Cookie 的首部欄位資訊** , 通知客戶端儲存 Cookie。當下次客戶端再往該伺服器傳送請求時,客戶端會自動在請求報文中加入 Cookie 值後傳送出去。 伺服器端發現客戶端傳送過來的 Cookie 後, 會去檢查究竟是從哪一個客戶端發來的連線請求, 然後對比伺服器上的記錄,最後得到之前的狀態資訊。

http工作流程

4. 缺陷

  • cookie會被附加在每個HTTP請求中,所以無形中增加了流量。
  • 由於在HTTP請求中的cookie是明文傳遞的 ,所以安全性成問題。(除非用HTTPS)
  • Cookie的大小限制在4KB左右。對於複雜的儲存需求來說是不夠用的。

5.2 Session

Session原意是會話的意思,放在Web訪問中,是指使用者通過瀏覽器進入某一網站時,就與網站之間建立了唯一的會話關係。

1. 工作機制

session機制是一種伺服器端的機制,伺服器使用一種類似於散列表的結構(也可能就是使用散列表)來儲存資訊,儘可能確保各個ID的全域性唯一性。
當程式需要為某個客戶端的請求建立一個session的時候,伺服器首先檢查這個客戶端的請求裡是否已包含了一個session標識- 稱為session id,如果已包含一個session id則說明以前已經為此客戶端建立過session,伺服器就按照session id把這個session檢索出來使用(如果檢索不到,可能會新建一個),如果客戶端請求不包含session id,則為此客戶端建立一個session並且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字串,這個session id將被在本次響應中返回給客戶端儲存。

2. 伺服器將session id響應返回給瀏覽器:

  • 採用Cookie方式,採用HTTP協議中的Cookie機制,當伺服器產生session id後,通過Set-Cookie擴充套件頭將session id傳送到瀏覽器,此後Cookie頭裡會攜帶session id資訊。
  • 考慮到瀏覽器會禁止使用Cookie,所以另一種方式是採用URL重寫。就是把session id直接附加在URL路徑的後面。
    附加方式也有兩種,一種是作為URL路徑的附加資訊,表現形式為http://…/xxx;jsessionid=ByOK … 99zWpBng!-145788764
    另一種是作為查詢字串附加在URL後面,表現形式為http://…/xxx?jsessionid=ByOK … 99zWpBng!-145788764
    這兩種方式對於使用者來說是沒有區別的,只是伺服器在解析的時候處理的方式不同,採用第一種方式也有利於把session id的資訊和正常程式引數區分開來。為了在整個互動過程中始終保持狀態,就必須在每個客戶端可能請求的路徑後面都包含這個session id。

5.3 Cookie 和 Session的區別

  1. 存取方式的不同:
    Cookie中只能保管ASCII字串,假如需求存取Unicode字元或者二進位制資料,需求先進行編碼。Cookie中也不能直接存取Java物件。若要儲存略微複雜的資訊,運用Cookie是比較艱難的。
    而Session中能夠存取任何型別的資料,包括而不限於String、Integer、List、Map等。Session中也能夠直接保管JavaBean乃至任何Java類,物件等,運用起來十分便當,能夠把Session看做是一個Java容器類。

  2. 隱私策略的不同
    Cookie儲存在客戶端閱讀器中,對客戶端是可見的,客戶端的一些程式可能會窺探、複製以至修正Cookie中的內容。而Session儲存在伺服器上,對客戶端是透明的,
    不存在敏感資訊洩露的風險。假如選用Cookie,比較好的方法是,敏感的資訊如賬號密碼等儘量不要寫到Cookie中。最好是像Google、Baidu那樣將Cookie資訊加密,
    提交到伺服器後再進行解密,保證Cookie中的資訊只要本人能讀得懂。而假如選擇Session就省事多了,反正是放在伺服器上,Session裡任何隱私都能夠有效的保護。

  3. 有效期上的不同
    使用過Google的人都曉得,假如登入過Google,則Google的登入資訊長期有效。使用者不用每次訪問都重新登入,Google會持久地記載該使用者的登入資訊。
    要到達這種效果,運用Cookie會是比較好的選擇。只需要設定Cookie的過期時間屬性為一個很大很大的數字。
    由於Session依賴於名為JSESSIONID的Cookie,而Cookie JSESSIONID的過期時間默許為–1,只需關閉了閱讀器該Session就會失效,因而Session不能完成資訊永世有效的效果。
    運用URL地址重寫也不能完成。而且假如設定Session的超時時間過長,伺服器累計的Session就會越多,越容易招致記憶體溢位。

  4. 伺服器壓力的不同
    Session是保管在伺服器端的,每個使用者都會產生一個Session。假如併發訪問的使用者十分多,會產生十分多的Session,耗費大量的記憶體。
    因而像Google、Baidu、Sina這樣併發訪問量極高的網站,是不太可能運用Session來追蹤客戶會話的。
    而Cookie保管在客戶端,不佔用伺服器資源。假如併發閱讀的使用者十分多,Cookie是很好的選擇。關於Google、Baidu、Sina來說,Cookie或許是唯一的選擇。

  5. 瀏覽器支援的不同
    Cookie是需要客戶端瀏覽器支援的。假如客戶端禁用了Cookie,或者不支援Cookie,則會話跟蹤會失效。關於WAP上的應用,常規的Cookie就派不上用場了。
    假如客戶端瀏覽器不支援Cookie,需要運用Session以及URL地址重寫。需要注意的是一切用到Session程式的URL都要進行URL地址重寫,否則Session會話跟蹤還會失效
    關於WAP應用來說,Session+URL地址重寫或許是它唯一的選擇。
    假如客戶端支援Cookie,則Cookie既能夠設為本瀏覽器視窗以及子視窗內有效(把過期時間設為–1),也能夠設為一切閱讀器視窗內有效(把過期時間設為某個大於0的整數)。
    但Session只能在本閱讀器視窗以及其子視窗內有效。假如兩個瀏覽器視窗互不相干,它們將運用兩個不同的Session。(IE8下不同視窗Session相干)

  6. 跨域支援上的不同
    Cookie支援跨域名訪問,例如將domain屬性設定為“.biaodianfu.com”,則以“.biaodianfu.com”為字尾的一切域名均能夠訪問該Cookie。跨域名Cookie如今被普遍用在網路中,例如Google、Baidu、Sina等。而Session則不會支援跨域名訪問。Session僅在他所在的域名內有效。
    僅運用Cookie或者僅運用Session可能完成不了理想的效果。這時應該嘗試一下同時運用Cookie與Session。Cookie與Session的搭配運用在實踐專案中會完成很多意想不到的效果。

六、HTTP的安全協議

6.1 基本概念

HTTP:是網際網路上應用最為廣泛的一種網路協議,是一個客戶端和伺服器端請求和應答的標準(TCP),用於從WWW伺服器傳輸超文字到本地瀏覽器的傳輸協議,它可以使瀏覽器更加高效,使網路傳輸減少。
HTTPS:是以安全為目標的HTTP通道,簡單講是HTTP的安全版,即HTTP下加入SSL層/LS層。HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。可以理解為socket+SSL+http(https是在SSL上的http,底層用了SSL,應用層協議還是http。SSL底層用的是socket,對socket傳輸的資料進行加解密)。
結構

6.2 HTTPS的工作原理

(1) HTTPS涉及到的主體:
客戶端:通常是瀏覽器(Chrome、IE、FireFox等),也可以自己編寫的各種語言的客戶端程式。
服務端:一般指支援Https的網站,比如github、支付寶。
CA(Certificate Authorities)機構:Https證書籤發和管理機構,比如Symantec、Comodo、GoDaddy、GlobalSign。
(2) HTTPS工作流程
流程
基本分為三個階段:

  1. 認證伺服器。瀏覽器內建一個受信任的CA機構列表,並儲存了這些CA機構的證書。第一階段伺服器會提供經CA機構認證頒發的伺服器證書,如果認證該伺服器證書的CA機構,存在於瀏覽器的受信任CA機構列表中,並且伺服器證書中的資訊與當前正在訪問的網站(域名等)一致,那麼瀏覽器就認為服務端是可信的,並從伺服器證書中取得伺服器公鑰,用於後續流程。否則,瀏覽器將提示使用者,根據使用者的選擇,決定是否繼續。當然,我們可以管理這個受信任CA機構列表,新增我們想要信任的CA機構,或者移除我們不信任的CA機構。
  2. 協商會話金鑰。客戶端在認證完伺服器,獲得伺服器的公鑰之後,利用該公鑰與伺服器進行加密通訊,協商出兩個會話金鑰,分別是用於加密客戶端往服務端傳送資料的客戶端會話金鑰,用於加密服務端往客戶端傳送資料的服務端會話金鑰。在已有伺服器公鑰,可以加密通訊的前提下,還要協商兩個對稱金鑰的原因,是因為非對稱加密相對複雜度更高,在資料傳輸過程中,使用對稱加密,可以節省計算資源。另外,會話金鑰是隨機生成,每次協商都會有不一樣的結果,所以安全性也比較高。
  3. 加密通訊。此時客戶端伺服器雙方都有了本次通訊的會話金鑰,之後傳輸的所有Http資料,都通過會話金鑰加密。這樣網路上的其它使用者,將很難竊取和篡改客戶端和服務端之間傳輸的資料,從而保證了資料的私密性和完整性。

6.3 SSL/TSL

  • SSL(Secure Socket Layer,安全套接字層):1994年為 Netscape 所研發,SSL 協議位於 TCP/IP 協議與各種應用層協議之間,為資料通訊提供安全支援。
  • TLS(Transport Layer Security,傳輸層安全):其前身是 SSL,它最初的幾個版本(SSL 1.0、SSL 2.0、SSL 3.0)由網景公司開發,1999年從 3.1 開始被 IETF 標準化並改名,發展至今已經有 TLS 1.0、TLS 1.1、TLS 1.2 三個版本。SSL3.0和TLS1.0由於存在安全漏洞,已經很少被使用到。TLS 1.3 改動會比較大,目前還在草案階段,目前使用最廣泛的是TLS 1.1、TLS 1.2。

6.4 加密演算法

  1. 對稱加密
    有流式、分組兩種,加密和解密都是使用的同一個金鑰。
    例如:DES、AES-GCM、ChaCha20-Poly1305等
    對稱
    缺點是:
    (1)不同的客戶端、伺服器數量龐大,所以雙方都需要維護大量的金鑰,維護成本很高
    (2)因每個客戶端、伺服器的安全級別不同,金鑰極易洩露
  2. 非對稱加密
    加密使用的金鑰和解密使用的金鑰是不相同的,分別稱為:公鑰、私鑰,公鑰和演算法都是公開的,私鑰是保密的。非對稱加密演算法效能較低,但是安全性超強,由於其加密特性,非對稱加密演算法能加密的資料長度也是有限的。
    例如:RSA、DSA、ECDSA、 DH、ECDHE
    非對稱
    缺點:
    (1)公鑰是公開的(也就是黑客也會有公鑰),所以第 ④ 步私鑰加密的資訊,如果被黑客截獲,其可以使用公鑰進行解密,獲取其中的內容
  3. 對稱與非對稱綜合
    綜合
    SSL 證書中包含的具體內容有:
    (1)證書的釋出機構CA
    (2)證書的有效期
    (3)公鑰
    (4)證書所有者
    (5)簽名
  4. 雜湊演算法
    將任意長度的資訊轉換為較短的固定長度的值,通常其長度要比資訊小得多,且演算法不可逆。
    例如:MD5、SHA-1、SHA-2、SHA-256 等
  5. 數字簽名
    簽名就是在資訊的後面再加上一段內容(資訊經過hash後的值),可以證明資訊沒有被修改過。hash值一般都會加密後(也就是簽名)再和資訊一起傳送,以保證這個hash值不被修改。

6.5 HTTPS 缺點:

(1)SSL 證書費用很高,以及其在伺服器上的部署、更新維護非常繁瑣
(2)HTTPS 降低使用者訪問速度(多次握手)
(3)網站改用HTTPS 以後,由HTTP 跳轉到 HTTPS 的方式增加了使用者訪問耗時(多數網站採用302跳轉)
(4)HTTPS 涉及到的安全演算法會消耗 CPU資源,需要增加大量機器(https訪問過程需要加解密)