本文包含內容
- Http特點
- 一次完整的網絡訪問流程
- URI和URL的區別
- Http報文結構,首部字段說明
- Http的請求方法
- Http狀態碼
- Cookie和Session分別幹嘛的
- Http和Https的關係
- Https建立SSL全過程
- Http1.0、1.1、SPDY、2.0的區別
- 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 後,會去檢查究竟是從哪一 個客戶端發來的連接請求,然後對比服務器上的記錄,最後得到之前 的狀態信息。
用戶在瀏覽器輸入地址後發生的網絡訪問事件
- 瀏覽器分析鏈接指向頁面URL
- 瀏覽器向DNS請求解析www.baidu.com的IP地址
- 域名系統DNS解析出百度服務器地址IP爲192.168.22.11
- 瀏覽器與服務器建立TCP連接(服務端的地址爲192.168.22.11:80)
- 瀏覽器發出Get請求 : Get/chn/yxsz/index.html
- 服務器給出響應,把文件index.html發送給瀏覽器
- 釋放TCP連接
- 瀏覽器解析內容,顯示請求到的內容
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報文結構,首部字段說明
請求報文
響應報文
報文結構
報頭
通用報頭
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請求方法
-
Get:獲取資源。GET 方法用來請求訪問已被 URI 識別的資源。
-
POST:傳輸實體主體。POST 方法用來傳輸實體的主體。
-
PUT:傳輸文件。PUT 方法用來傳輸文件。就像 FTP 協議的文件上傳一樣,要求在請 求報文的主體中包含文件內容,然後保存到請求 URI 指定的位置。
-
HEAD:獲得報文首部,HEAD 方法和 GET 方法一樣,只是不返回報文主體部分。用於確認 URI 的有效性及資源更新的日期時間等。
-
DELETE:刪除文件。DELETE 方法用來刪除文件,是與 PUT 相反的方法。DELETE 方法按 請求 URI 刪除指定的資源。
-
OPTIONS:詢問支持的方法。OPTIONS 方法用來查詢針對請求 URI 指定的資源支持的方法。
-
TRACE:追蹤路徑。TRACE 方法是讓 Web 服務器端將之前的請求通信環回給客戶端的方法。
Http狀態碼
1xx 通知
2xx 請求成功
3xx 重定向
4xx 客戶端錯誤
5xx 服務器錯誤
編碼提升傳輸速率
-
HTTP 在傳輸數據時可以按照數據原貌直接傳輸,但也可以在傳輸過 程中通過編碼提升傳輸速率。通過在傳輸時編碼,能有效地處理大量 的訪問請求。但是,編碼的操作需要計算機來完成,因此會消耗更多 的 CPU 等資源。
-
壓縮傳輸的內容編碼
向待發送郵件內增加附件時,爲了使郵件容量變小,我們會先用 ZIP 壓縮文件之後再添加附件發送。HTTP 協議中有一種被稱爲內容編碼 的功能也能進行類似的操作。
內容編碼指明應用在實體內容上的編碼格式,並保持實體信息原樣壓縮。內容編碼後的實體由客戶端接收並負責解碼。
常用的內容編碼有以下幾種。
gzip(GNU zip) compress(UNIX 系統的標準壓縮) deflate(zlib) identity(不進行編碼)
-
分割發送的分塊傳輸編碼
在 HTTP 通信過程中,請求的編碼實體資源尚未全部傳輸完成之前, 瀏覽器無法顯示請求頁面。在傳輸大容量數據時,通過把數據分割成 多塊,能夠讓瀏覽器逐步顯示頁面。
這種把實體主體分塊的功能稱爲分塊傳輸編碼(Chunked Transfer Coding)。
分塊傳輸編碼會將實體主體分成多個部分(塊)。每一塊都會用十六 進制來標記塊的大小,而實體主體的最後一塊會使用“0(CR+LF)”來標 記。
使用分塊傳輸編碼的實體主體會由接收的客戶端負責解碼,恢復到編 碼前的實體主體。
HTTP/1.1 中存在一種稱爲傳輸編碼(Transfer Coding)的機制,它可 以在通信時按某種編碼方式傳輸,但只定義作用於分塊傳輸編碼中。
-
獲取部分內容的範圍請求
指定範圍發送的請 求叫做範圍請求(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的關係
-
HTTP+ 加密 + 認證 + 完整性保護 = HTTPS
-
HTTPS 是身披 SSL 外殼的 HTTP
HTTPS 並非是應用層的一種新協議。只是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)協議代 替而已。
通常,HTTP 直接和 TCP 通信。當使用 SSL時,則演變成先和 SSL通 信,再由 SSL和 TCP 通信了。簡言之,所謂 HTTPS,其實就是身披 SSL協議這層外殼的 HTTP。
-
HTTPS 採用混合加密機制
HTTPS 採用共享密鑰加密和公開密鑰加密兩者並用的混合加密 機制。若密鑰能夠實現安全交換,那麼有可能會考慮僅使用公開 密鑰加密來通信。但是公開密鑰加密與共享密鑰加密相比,其處 理速度要慢。
所以應充分利用兩者各自的優勢,將多種方法組合起來用於通 信。在交換密鑰環節使用公開密鑰加密方式,之後的建立通信交 換報文階段則使用共享密鑰加密方式。
-
證明公開密鑰正確性的證書
使用由數字證書認證機構(CA,Certificate Authority)和其相關機關頒發的公開密鑰證書。
服務器會將這份由數字證書認證機構頒發的公鑰證書發送給客戶端,以進行公開密鑰加密方式通信。公鑰證書也可叫做數字證書或直接稱 爲證書。
接到證書的客戶端可使用數字證書認證機構的公開密鑰,對那張證書 上的數字簽名進行驗證,一旦驗證通過,客戶端便可明確兩件事: 一,認證服務器的公開密鑰的是真實有效的數字證書認證機構。二, 服務器的公開密鑰是值得信賴的。
此處認證機關的公開密鑰必須安全地轉交給客戶端。使用通信方式 時,如何安全轉交是一件很困難的事,因此,多數瀏覽器開發商發佈 版本時,會事先在內部植入常用認證機關的公開密鑰。
-
HTTPS 比 HTTP 要慢 2 到 100 倍
SSL的慢分兩種。一種是指通信慢。另一種是指由於大量消耗 CPU 及內存等資源,導致處理速度變慢。
和使用 HTTP 相比,網絡負載可能會變慢 2 到 100 倍。除去和 TCP 連接、發送 HTTP 請求 • 響應以外,還必須進行 SSL通信, 因此整體上處理通信量不可避免會增加。
另一點是 SSL必須進行加密處理。在服務器和客戶端都需要進行 加密和解密的運算處理。因此從結果上講,比起 HTTP 會更多地 消耗服務器和客戶端的硬件資源,導致負載增強。
針對速度變慢這一問題,並沒有根本性的解決方案,我們會使用 SSL加速器這種(專用服務器)硬件來改善該問題。該硬件爲 SSL通信專用硬件,相對軟件來講,能夠提高數倍 SSL的計算速 度。僅在 SSL處理時發揮 SSL加速器的功效,以分擔負載。
Https建立SSL全過程
步驟 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 報文等。
-
多路複用流
通過單一的 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--