關於Http你至少需要知道這些內容

本文包含內容

  1. Http特點
  2. 一次完整的網絡訪問流程
  3. URI和URL的區別
  4. Http報文結構,首部字段說明
  5. Http的請求方法
  6. Http狀態碼
  7. Cookie和Session分別幹嘛的
  8. Http和Https的關係
  9. Https建立SSL全過程
  10. Http1.0、1.1、SPDY、2.0的區別
  11. Http Post傳輸數據幾種格式

Http特點

1. 支持c/s模式

Http用於客戶端和服務端之間通信

HTTP 協議規定,請求從客戶端發出,最後服務器端響應該請求並返回。換句話說,肯定是先從客戶端開始建立通信的,服務器端在沒有 接收到請求之前不會發送響應。

2. 無狀態

HTTP 是一種不保存狀態,即無狀態(stateless)協議。

HTTP 協議自 身不對請求和響應之間的通信狀態進行保存。也就是說在 HTTP 這個 級別,協議對於發送過的請求或響應都不做持久化處理。

3. 靈活

HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。

4. 持久連接

在Http1.1使用了持久連接

持久連接的特點是,只要任意一端沒有明確提出斷開連接,則保持 TCP 連接狀態。

持久連接旨在建立1次TCP連接後進行多次請求和響應的交互。

持久連接的好處在於減少了 TCP 連接的重複建立和斷開所造成的額外開銷,減輕了服務器端的負載。另外,減少開銷的那部分時間,使 HTTP 請求和響應能夠更早地結束,這樣 Web 頁面的顯示速度也就相 應提高了。

在 HTTP/1.1 中,所有的連接默認都是持久連接,但在 HTTP/1.0 內並未標準化。雖然有一部分服務器通過非標準的手段實現了持久連接, 但服務器端不一定能夠支持持久連接。毫無疑問,除了服務器端,客 戶端也需要支持持久連接。

管線化 : 持久連接使得多數請求以管線化(pipelining)方式發送成爲可能。從 前發送請求後需等待並收到響應,才能發送下一個請求。管線化技術 出現後,不用等待響應亦可直接發送下一個請求。

這樣就能夠做到同時並行發送多個請求,而不需要一個接一個地等待 響應了。

5. 使用Cookie的狀態管理

Cookie 技術通過在請求和響應報文中寫入 Cookie 信 息來控制客戶端的狀態。

Cookie 會根據從服務器端發送的響應報文內的一個叫做 Set-Cookie 的 首部字段信息,通知客戶端保存 Cookie。當下次客戶端再往該服務器 發送請求時,客戶端會自動在請求報文中加入 Cookie 值後發送出 去。

服務器端發現客戶端發送過來的 Cookie 後,會去檢查究竟是從哪一 個客戶端發來的連接請求,然後對比服務器上的記錄,最後得到之前 的狀態信息。


用戶在瀏覽器輸入地址後發生的網絡訪問事件

  1. 瀏覽器分析鏈接指向頁面URL
  2. 瀏覽器向DNS請求解析www.baidu.com的IP地址
  3. 域名系統DNS解析出百度服務器地址IP爲192.168.22.11
  4. 瀏覽器與服務器建立TCP連接(服務端的地址爲192.168.22.11:80)
  5. 瀏覽器發出Get請求 : Get/chn/yxsz/index.html
  6. 服務器給出響應,把文件index.html發送給瀏覽器
  7. 釋放TCP連接
  8. 瀏覽器解析內容,顯示請求到的內容

網絡訪問事件流程.png


URI和URL的關係

URI : 統一資源標識符,是由某個協議方案表示的資源的定位標識符。協議方案是指訪問資源所使用的協議類型名稱。採用 HTTP 協議時,協議方案就是 http。除此之外,還有 ftp、mailto、telnet、file 等。標準的 URI 協議方案有 30 種左右,由隸屬於 國際互聯網資源管理的非營利社團 ICANN(Internet Corporation for Assigned Names and Numbers,互聯網名稱與數字地址分配機構)的 IANA(Internet Assigned Numbers Authority,互聯網號碼分配局)管理 頒佈。

URL:統一資源定位符。URI用字符串標識某一互聯網資源,而 URL表示資源的地點(互聯 網上所處的位置)。可見URL是URI的子集。


Http報文結構,首部字段說明

請求報文

Http請求報文.png

響應報文

Http響應報文.png

報文結構

報文結構.png

報頭

通用報頭

Date : 時間
Connection :
Cache-Control:

請求報頭

Host:請求的主機名,允許多個域名同處一個IP地址,即虛擬主機。

User-Agent:發送請求的瀏覽器類型、操作系統等信息。

Accept:客戶端可識別的內容類型列表,用於指定客戶端接收哪些類型的信息。

Accept-Encoding:客戶端可識別的數據編碼。

Accept-Language:表示瀏覽器所支持的語言類型。

Connection:允許客戶端和服務器指定與請求/響應連接有關的選項。例如,這時爲Keep-Alive則表示 保持連接。

Transfer-Encoding:告知接收端爲了保證報文的可靠傳輸,對報文采用了什麼編碼方式。

響應報頭

用於服務器傳遞自身信息的響應。常見的響應報頭如下所示。

Location:用於重定向接收者到一個新的位置,常用在更換域名的時候。

Server:包含服務器用來處理請求的系統信息,與User-Agent請求報頭是相對應的。

實體報頭

實體報頭用來定義被傳送資源的信息,其既可用於請求也可用於響應。請求和響應消息都可以傳送一 個實體。常見的實體報頭如下所示。

Content-Type:發送給接收者的實體正文的媒體類型。

Content-Lenght:實體正文的長度。 、Content-Language:描述資源所用的自然語言。

Content-Encoding:實體報頭被用作媒體類型的修飾符。它的值指示了已經被應用到實體正文的附加 內容的編碼,因而要獲得Content-Type報頭域中所引用的媒體類型,必須採用相應的解碼機制。

Last-Modified:實體報頭用於指示資源的最後修改日期和時間。

Expires:實體報頭給出響應過期的日期和時間。


Http請求方法

  1. Get:獲取資源。GET 方法用來請求訪問已被 URI 識別的資源。

  2. POST:傳輸實體主體。POST 方法用來傳輸實體的主體。

  3. PUT:傳輸文件。PUT 方法用來傳輸文件。就像 FTP 協議的文件上傳一樣,要求在請 求報文的主體中包含文件內容,然後保存到請求 URI 指定的位置。

  4. HEAD:獲得報文首部,HEAD 方法和 GET 方法一樣,只是不返回報文主體部分。用於確認 URI 的有效性及資源更新的日期時間等。

  5. DELETE:刪除文件。DELETE 方法用來刪除文件,是與 PUT 相反的方法。DELETE 方法按 請求 URI 刪除指定的資源。

  6. OPTIONS:詢問支持的方法。OPTIONS 方法用來查詢針對請求 URI 指定的資源支持的方法。

  7. TRACE:追蹤路徑。TRACE 方法是讓 Web 服務器端將之前的請求通信環回給客戶端的方法。


Http狀態碼

1xx 通知

2xx 請求成功

3xx 重定向

4xx 客戶端錯誤

5xx 服務器錯誤


編碼提升傳輸速率

  1. HTTP 在傳輸數據時可以按照數據原貌直接傳輸,但也可以在傳輸過 程中通過編碼提升傳輸速率。通過在傳輸時編碼,能有效地處理大量 的訪問請求。但是,編碼的操作需要計算機來完成,因此會消耗更多 的 CPU 等資源。

  2. 壓縮傳輸的內容編碼

    向待發送郵件內增加附件時,爲了使郵件容量變小,我們會先用 ZIP 壓縮文件之後再添加附件發送。HTTP 協議中有一種被稱爲內容編碼 的功能也能進行類似的操作。

    內容編碼指明應用在實體內容上的編碼格式,並保持實體信息原樣壓縮。內容編碼後的實體由客戶端接收並負責解碼。

    常用的內容編碼有以下幾種。

    gzip(GNU zip) compress(UNIX 系統的標準壓縮) deflate(zlib) identity(不進行編碼)

  3. 分割發送的分塊傳輸編碼

    在 HTTP 通信過程中,請求的編碼實體資源尚未全部傳輸完成之前, 瀏覽器無法顯示請求頁面。在傳輸大容量數據時,通過把數據分割成 多塊,能夠讓瀏覽器逐步顯示頁面。

    這種把實體主體分塊的功能稱爲分塊傳輸編碼(Chunked Transfer Coding)。

    分塊傳輸編碼會將實體主體分成多個部分(塊)。每一塊都會用十六 進制來標記塊的大小,而實體主體的最後一塊會使用“0(CR+LF)”來標 記。

    使用分塊傳輸編碼的實體主體會由接收的客戶端負責解碼,恢復到編 碼前的實體主體。

    HTTP/1.1 中存在一種稱爲傳輸編碼(Transfer Coding)的機制,它可 以在通信時按某種編碼方式傳輸,但只定義作用於分塊傳輸編碼中。

  4. 獲取部分內容的範圍請求

    指定範圍發送的請 求叫做範圍請求(Range Request)。

    對一份 10 000 字節大小的資源,如果使用範圍請求,可以只請求 5001~10 000 字節內的資源。

    執行範圍請求時,會用到首部字段 Range 來指定資源的 byte 範圍。 byte 範圍的指定形式如下。

    5001~10 000 字節

     Range: bytes=5001-10000
    

    從 5001 字節之後全部的

     Range: bytes=5001-
    

    從一開始到 3000 字節和 5000~7000 字節的多重範圍

     Range: bytes=-3000, 5000-7000
    

Http和Https的關係

  1. HTTP+ 加密 + 認證 + 完整性保護 = HTTPS

  2. HTTPS 是身披 SSL 外殼的 HTTP

    HTTPS 並非是應用層的一種新協議。只是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)協議代 替而已。

    通常,HTTP 直接和 TCP 通信。當使用 SSL時,則演變成先和 SSL通 信,再由 SSL和 TCP 通信了。簡言之,所謂 HTTPS,其實就是身披 SSL協議這層外殼的 HTTP。

    Http和Https的層次.png

  3. HTTPS 採用混合加密機制

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

    所以應充分利用兩者各自的優勢,將多種方法組合起來用於通 信。在交換密鑰環節使用公開密鑰加密方式,之後的建立通信交 換報文階段則使用共享密鑰加密方式。

  4. 證明公開密鑰正確性的證書

    使用由數字證書認證機構(CA,Certificate Authority)和其相關機關頒發的公開密鑰證書。

    服務器會將這份由數字證書認證機構頒發的公鑰證書發送給客戶端,以進行公開密鑰加密方式通信。公鑰證書也可叫做數字證書或直接稱 爲證書。

    接到證書的客戶端可使用數字證書認證機構的公開密鑰,對那張證書 上的數字簽名進行驗證,一旦驗證通過,客戶端便可明確兩件事: 一,認證服務器的公開密鑰的是真實有效的數字證書認證機構。二, 服務器的公開密鑰是值得信賴的。

    此處認證機關的公開密鑰必須安全地轉交給客戶端。使用通信方式 時,如何安全轉交是一件很困難的事,因此,多數瀏覽器開發商發佈 版本時,會事先在內部植入常用認證機關的公開密鑰。

  5. HTTPS 比 HTTP 要慢 2 到 100 倍

    SSL的慢分兩種。一種是指通信慢。另一種是指由於大量消耗 CPU 及內存等資源,導致處理速度變慢。

    和使用 HTTP 相比,網絡負載可能會變慢 2 到 100 倍。除去和 TCP 連接、發送 HTTP 請求 • 響應以外,還必須進行 SSL通信, 因此整體上處理通信量不可避免會增加。

    另一點是 SSL必須進行加密處理。在服務器和客戶端都需要進行 加密和解密的運算處理。因此從結果上講,比起 HTTP 會更多地 消耗服務器和客戶端的硬件資源,導致負載增強。

    針對速度變慢這一問題,並沒有根本性的解決方案,我們會使用 SSL加速器這種(專用服務器)硬件來改善該問題。該硬件爲 SSL通信專用硬件,相對軟件來講,能夠提高數倍 SSL的計算速 度。僅在 SSL處理時發揮 SSL加速器的功效,以分擔負載。


Https建立SSL全過程

Https通信.png

步驟 1: 客戶端通過發送 Client Hello 報文開始 SSL通信。報文中包 含客戶端支持的 SSL的指定版本、加密組件(Cipher Suite)列表(所 使用的加密算法及密鑰長度等)。

步驟 2: 服務器可進行 SSL通信時,會以 Server Hello 報文作爲應答。和客戶端一樣,在報文中包含 SSL版本以及加密組件。服務器的 加密組件內容是從接收到的客戶端加密組件內篩選出來的。

步驟 3: 之後服務器發送 Certificate 報文。報文中包含公開密鑰證 書。

步驟 4: 最後服務器發送 Server Hello Done 報文通知客戶端,最初階 段的 SSL握手協商部分結束。

步驟 5: SSL第一次握手結束之後,客戶端以 Client Key Exchange 報 文作爲迴應。報文中包含通信加密中使用的一種被稱爲 Pre-master secret 的隨機密碼串。該報文已用步驟 3 中的公開密鑰進行加密。

步驟 6: 接着客戶端繼續發送 Change Cipher Spec 報文。該報文會提 示服務器,在此報文之後的通信會採用 Pre-master secret 密鑰加密。

步驟 7: 客戶端發送 Finished 報文。該報文包含連接至今全部報文的 整體校驗值。這次握手協商是否能夠成功,要以服務器是否能夠正確 解密該報文作爲判定標準。

步驟 8: 服務器同樣發送 Change Cipher Spec 報文。

步驟 9: 服務器同樣發送 Finished 報文。

步驟 10: 服務器和客戶端的 Finished 報文交換完畢之後,SSL連接 就算建立完成。當然,通信會受到 SSL的保護。從此處開始進行應用 層協議的通信,即發送 HTTP 請求。

步驟 11: 應用層協議通信,即發送 HTTP 響應。

步驟 12: 最後由客戶端斷開連接。斷開連接時,發送 close_notify 報 文。上圖做了一些省略,這步之後再發送 TCP FIN 報文來關閉與 TCP 的通信。

在以上流程中,應用層發送數據時會附加一種叫做 MAC(Message Authentication Code)的報文摘要。MAC 能夠查知報文是否遭到篡 改,從而保護報文的完整性。


Cookie和Session分別幹嘛的,有什麼區別

一般會使用 Cookie 來管理 Session(會話)。

步驟 1: 客戶端把用戶 ID 和密碼等登錄信息放入報文的實體部分, 通常是以 POST 方法把請求發送給服務器。而這時,會使用 HTTPS 通信來進行 HTML表單畫面的顯示和用戶輸入數據的發送。

步驟 2: 服務器會發放用以識別用戶的 Session ID。通過驗證從客戶 端發送過來的登錄信息進行身份認證,然後把用戶的認證狀態與 Session ID 綁定後記錄在服務器端。

向客戶端返回響應時,會在首部字段 Set-Cookie 內寫入 Session ID(如 PHPSESSID=028a8c…)。

你可以把 Session ID 想象成一種用以區分不同用戶的等位號。

然而,如果 Session ID 被第三方盜走,對方就可以僞裝成你的身份進 行惡意操作了。因此必須防止 Session ID 被盜,或被猜出。爲了做到 這點,Session ID 應使用難以推測的字符串,且服務器端也需要進行 有效期的管理,保證其安全性。

另外,爲減輕跨站腳本攻擊(XSS)造成的損失,建議事先在 Cookie 內加上 httponly 屬性。

步驟 3: 客戶端接收到從服務器端發來的 Session ID 後,會將其作爲 Cookie 保存在本地。下次向服務器發送請求時,瀏覽器會自動發送 Cookie,所以 Session ID 也隨之發送到服務器。服務器端可通過驗證 接收到的 Session ID 識別用戶和其認證狀態。

總結:cookie用於存儲用戶數據,行爲,比如存儲用戶上次登錄輸入的內容。可以存儲在內存中,也可以序列化到本地,根據超時時間進行銷燬,或者被服務端新set-cookie來覆蓋。

session是一種抽象的會話,比如,只有登錄了才能查看我的訂單,這時候有一個sessionId來標識是否登錄了,這個sessionID可以由cookie來管理。


Http1.0、1.1、2.0區別

Http1.0/1.1:
  • 一條連接上只可發送一個請求。
  • 請求只能從客戶端開始。客戶端不可以接收除響應以外的指 令。
  • 請求 / 響應首部未經壓縮就發送。首部信息越多延遲越大。
  • 發送冗長的首部。每次互相發送相同的首部造成的浪費較 多。
  • 可任意選擇數據壓縮格式。非強制壓縮發送。
Http SPDY

SPDY 沒有完全改寫 HTTP 協議,而是在 TCP/IP 的應用層與運輸層之 間通過新加會話層的形式運作。同時,考慮到安全性問題,SPDY 規 定通信中使用 SSL。

SPDY 以會話層的形式加入,控制對數據的流動,但還是採用 HTTP 建立通信連接。因此,可照常使用 HTTP 的 GET 和 POST 等方 法、 Cookie 以及 HTTP 報文等。

SPDY設計.png

  • 多路複用流

    通過單一的 TCP 連接,可以無限制處理多個 HTTP 請求。所有請求 的處理都在一條 TCP 連接上完成,因此 TCP 的處理效率得到提高。

  • 賦予請求優先級

    SPDY 不僅可以無限制地併發處理請求,還可以給請求逐個分配優先 級順序。這樣主要是爲了在發送多個請求時,解決因帶寬低而導致響 應變慢的問題。

  • 壓縮 HTTP 首部

    壓縮 HTTP 請求和響應的首部。這樣一來,通信產生的數據包數量和 發送的字節數就更少了。

  • 推送功能

    支持服務器主動向客戶端推送數據的功能。這樣,服務器可直接發送 數據,而不必等待客戶端的請求。

  • 服務器提示功能

    服務器可以主動提示客戶端請求所需的資源。由於在客戶端發現資源 之前就可以獲知資源的存在,因此在資源已緩存等情況下,可以避免發送不必要的請求。

這個小哥說的挺好


Http Post傳輸數據幾種格式

application/x-www-form-urlencoded

這應該是最常見的 POST 提交數據的方式了。瀏覽器的原生 表單,如果不設置 enctype 屬性,那麼最終就會以 application/x-www-form-urlencoded 方式提交數據。

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8

title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
  • 首先,Content-Type 被指定爲 application/x-www-form-urlencoded
  • 其次,提交的數據按照 key1=val1&key2=val2 的方式進行編碼,key 和 val 都進行了 URL 轉碼。
  • 大部分服務端語言都對這種方式有很好的支持。
application/json
  • Content-Type 被指定爲application/json

  • 可以方便的提交複雜的結構化數據,特別適合 RESTful 的接口

  • 各大抓包工具如 Chrome 自帶的開發者工具、Firebug、Fiddler,都會以樹形結構展示 JSON 數據,非常友好

    POST http://www.example.com HTTP/1.1
    Content-Type: application/json;charset=utf-8

    {“title”:“test”,“sub”:[1,2,3]}

text/xml

Content-Type: text/xml

POST http://www.example.com HTTP/1.1 
Content-Type: text/xml

<?xml version="1.0"?>
<methodCall>
    <methodName>examples.getStateName</methodName>
    <params>
        <param>
            <value><i4>41</i4></value>
        </param>
    </params>
</methodCall>
multipart/form-data
  • 使用表單上傳文件時,必須讓 表單的 enctype 等於 multipart/form-data

  • 首先生成了一個 boundary 用於分割不同的字段,爲了避免與正文內容重複,boundary 很長很複雜。

  • 然後 Content-Type 裏指明瞭數據是以 multipart/form-data 來編碼,本次請求的 boundary 是什麼內容

  • 消息主體裏按照字段個數又分爲多個結構類似的部分,每部分都是以 --boundary 開始

  • 緊接着是內容描述信息

  • 然後是回車

  • 最後是字段具體內容(文本或二進制)

  • 如果傳輸的是文件,還要包含文件名和文件類型信息。消息主體最後以 --boundary-- 標示結束。

      POST http://www.example.com HTTP/1.1
      Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
      
      ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
      Content-Disposition: form-data; name="text"
      
      title
      ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
      Content-Disposition: form-data; name="file"; filename="chrome.png"
      Content-Type: image/png
      
      PNG ... content of chrome.png ...
      ------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章