http通信協議的基本原理
- 在遠程通信場景中http協議是一種應用廣泛的應用層協議
http請求的通信流程
DNS服務
- Domain Name System
- DNS服務是和HTTP協議一樣位於應用層的協議
- 提供 域名、IP 之間的解析服務
http通信協議的組成
- http是基於應用層的協議
- 在傳輸層使用了TCP通信協議進行傳輸
協議的定義
- 協議是 兩個或多個需要進行網絡通信的程序 達成的一種約定
URI 和 URL
-
http請求通過URI定位資源
-
URL (Uniform Resource Locator)— 統一資源定位符,用於描述一個網絡上的資源
-
URI 用字符串標識某一互聯網資源
-
URL 則表示資源的地點(在互聯網中所處的位置)
-
URL 是 URI 的子集
http://www.xxx.com:80/java/index.html?name=mic#head
schema://host[:port#]/path/.../?[url-params]#[query-string]
schema 指定應用層使用的協議(如 http,https, ftp等)
host http服務器的IP地址活着域名
post# http服務器端口,默認80
path 訪問資源路徑
query-string 查詢字符串
所以,通過url地址,我們可以得到用戶使用http協議訪問指定服務器上對應進程的資源,並且攜帶的請求參數。
MIME Type
- 服務器通過用戶請求返回資源-》瀏覽器對資源解析並渲染
- 針對不同類型如圖片類型、視頻類型、Js等
- Q:瀏覽器如何識別當前類型並做不同渲染?
- A:通過 MIME Type
什麼是MIME Type?
- 描述消息內容類型的因特網標準
- 常見類型
- 文本文件:text/html text/plain text/css application/xhtml
- 圖片文件:image/jpeg image/gif image/png
- 視頻文件:video/mpeg video/quicktime
設置文件渲染類型的方式?
- Accept
- 表示客戶端希望接收的數據類型。服務器根據Accept請求頭產生相對應的數據。
- Content-Type
- 發送端發送的實體數據類型
response.setContentType("application/json;charset=utf-8") 表示服務端返回的數據格式是json
- 若Accept和Content-Type不一致,瀏覽器將無法解析
狀態碼的概念
- 當客戶端向服務端發送請求的時候,描述服務端返回的請求處理結果
類別 | 原因短語 | |
---|---|---|
1 | Information(信息狀態碼) | 接收的請求正在處理 |
2 | Success(成功狀態碼) | 請求正常處理完畢 |
3 | Redirection(重定向狀態碼) | 需要進行附加操作以完成請求 |
4 | Client Error(客戶端錯誤狀態碼) | 服務器無法處理請求 |
5 | Server Error(服務端錯誤狀態碼) | 服務器無法處理請求 |
不同請求的操作方式
- GET
- 客戶端發送一個URI地址去獲取服務端資源(一般用於查詢),傳輸數據有限制
- POST
- 傳輸實體給到服務端,讓服務端去保存(一般用於創建操作)
- PUT
- 向服務器發送數據,一般用於更新數據操作
- DELETE
- 一般用於刪除操作
- HEAD :獲得報文頭部
- OPTIONS : 詢問支持的方法
- TRACE :追蹤路徑
- CONNECT : 用隧道協議連接代理
REST架構風格
- 嚴格規定對於不同類型設置合適的請求方法
- Q:爲什麼要用REST架構?
- 服務化架構普及,http協議使用頻率越來越高
- 有狀態和無狀態請求混用
- 更好地利用http協議提供的規則
- REST面向資源,每一個URI代表一個資源
- 強調無狀態化,服務端不能存儲來自某個客戶請求中的信息
- 強調URL暴露資源時,不要再URI中出現動詞
- 合理使用http狀態碼、請求方法
http協議的完整組成
- 請求報文
- 響應報文
請求報文
- 請求行、請求頭部、請求數據
請求行
- 由方法字段、URL字段和http協議版本字段3個字段組成,使用空格分離
- ex:GET /data/index.jsp HTTP/1.1
- 方法字段就是HTTP使用的請求方法,比如常見的GET/POST
- 協議版本字段有兩種:HTTP1.0/HTTP1.1
- HTTP1.0 每個連接傳送一個請求或響應,請求就會關閉,沒有host字段
- HTTP1.1 在同一個連接中可以傳送多個請求和響應,可重疊和同時進行,必須有host字段
請求頭部
- 客戶端向服務器發送請求的時候必須指明請求類型,如有必要,還可以選擇發送其它的請求頭。大多數請求頭並非必須,但Content-Length除外
- 常見的請求頭有 Accept、Accept-Charset、Accept-Encoding、Content-Length、Host 等
請求數據
- 需要提交的數據
響應報文
- 響應行、響應頭、響應體
- 響應行:協議版本、狀態碼、狀態的原因短語
http協議中的擴展
-
傳輸文件過大的解決辦法?
- 對文件進行壓縮,減少文件大小
- 分割傳輸:在傳輸大容量數據時,把數據分割多塊,讓瀏覽器逐步顯示頁面
- 這種把實體主體分塊的功能成爲分塊傳輸編碼(Chunked Transfer Coding)
-
持久化連接
- HTTP/1.1中支持了持久化連接—只要一次連接建立之後,只要客戶端和服務端沒有明確提出斷開連接,tcp連接就會一直保持連接狀態
- 通過HTTP1.1中有一個Transport段,攜帶Connection:Keep-Alive,表示希望此條連接作爲持久連接。
- 持久化連接默認激活,可在報文中顯示地添加Connection:close首部表示事務結束之後要將連接關閉
-
管道化連接
- 不用等待響應亦可直接發送下一個請求。能夠實現同時並行發送多個請求
http協議的特點
- Http無狀態協議
- HTTP協議本身不會對請求和響應本身之間的通信狀態做保存
- 如何實現有狀態的協議
- 客戶端支持的cookie — Http協議中引入 cookie 技術,用來解決http協議無狀態的問題
- 通過在請求和響應報文中寫入Cookie信息來控制客戶端狀態
- Cookie根據服務器的響應報文 Set-Cookie 的首部字段信息,通知客戶端保存Cookie
- 當客戶端再次向服務器發送請求時,會自動在請求報文中假如Cookie值後發送出去
- 服務端支持的session—使用session機制來保存服務端的對象狀態
- 當程序需要爲某個客戶端創建一個session
- 服務器首先檢查客戶端請求是否包含了一個session標識 — session id
- 如果已有 session id — 說明已經爲客戶端創建過 session
- 服務端按照session id把這個session檢索出來使用
- 如果沒有 session id,則爲此客戶端創建一個session,並生成相關聯的 session id
Http協議安全傳輸
- http協議通信過程中,是基於明文通信的,底層基於TCP/IP協議進行通信
- 按照TCP/IP協議族的工作機制,通信內容可能遭到攔截和竊取
安全傳輸協議
- 由於HTTP協議通信的不安全性
- https — 對傳輸通道進行加密的方式
- https:一種加密的超文本傳輸協議
- 傳輸過程中對數據做了完全加密
- https同http協議一樣處於TCP傳輸層之上
- 在TCP協議層之上增加了一層SSL(Secure Socket Layer,安全層)或者 TLS(Transport Layer Security) 安全層傳輸協議組合使用用於構造加密通道
HTTPS實現加密傳輸機制
- 公鑰、私鑰和數字證書
HTTPS證書申請
- 服務器上生成CSR文件
- 證書申請文件:證書公鑰、Hash簽名算法、申請的域名、公司名稱、職位等信息
- CSR文件和其它所需證件上傳到CA認證機構
- CA機構收到認證申請,使用申請中的hash算法,對部分內容進行摘要
- CA機構使用自己的私鑰,對摘要信息進行簽名(相當於證書的唯一編號)
- CA機構把簽名過的證書通過郵件的形式發送到申請者手中
- 申請者收到證書之後部署到自己的web服務器中
HTTPS通信過程
- 客戶端發起請求
- 三次握手—TCP連接建立—生成隨機數client.random:用於生成對話密鑰
- 生成sessionid用於保持同一會話
- 服務端收到請求,然後響應
- 確認加密通道版本—服務端生成隨機數server.random:用於生成對話密鑰
- 確認使用的加密算法:用於後續的握手消息進行簽名防止篡改
- 服務器證書—CA機構頒發的證書
- 客戶端對收到的證書進行驗證
- 證書是否是上級CA簽發—是否過期—是否被吊銷
- 驗證簽名:私鑰簽名、公鑰驗籤
- CA機構在簽發證書的時候,會使用自己的私鑰對證書進行簽名
- 使用對應的算法字段對證書進行摘要,然後使用RSA算法對摘要進行私鑰簽名
- 私鑰簽名後只有公鑰才能進行驗籤
- 瀏覽器使用內置在操作系統上的CA機構的公鑰對服務器的證書進行驗籤
- 驗籤之後CA機構使用sha256(算法字段)進行證書摘要
- 客戶端再次使用sha256對證書內容進行一次摘要—對比得到的值
- 驗證通過之後—客戶端生成隨機數pre-master secret
- 客戶端根據之前的Client.random + sever.random + pre-master 對稱密鑰
- 使用證書中的公鑰進行加密
- 利用協商好的hash算法,對握手消息取hash值
- (取hash值,把握手消息做一個簽名,驗證消息是否被篡改過)
- 最後隨機數加密**“握手消息+握手消息 HASH 值(簽名)”** 發送給服務端
- 服務端接收到隨機數
- 用私鑰對密文進行解密
- 得到client.random/server.random/pre-master secret, HASH 值
- 與傳遞過來的hash值進行對比
- 隨機密碼加密一段握手消息(握手消息+握手消息的 HASH 值)給客戶端
- 客戶端接收消息
- 用隨機數解密並計算握手消息的HASH值,與服務端傳遞過來的HASH值一致,握手過程結束
- 之後通信過程根據交互過程中生成
- pre master secret /client.random/server.random 通過算法得出 session Key
- 作爲後續交互過程中的對稱密鑰