一、HTTP 請求流程
最初,HTTP 協議的出現主要是為了解決文本傳輸的難題,由于協議本身非常簡單,于是在此基礎上設想了很多應用方法并投入了實際使用,現在 HTTP 協議已經超出了 Web 這個框架的局限,被運用到了各種場景里,
目前主流的 HTTP 版本還是 HTTP/1.1,
HTTP 協議基于 TCP/IP 協議,會通過分層順序與對方進行通信,首先作為發送端的客戶端在應用層(HTTP 協議)發出一個想看某個 Web 頁面的 HTTP 請求;接著,在傳輸層(TCP 協議)把從應用層處收到的資料(HTTP 請求報文)進行分割,并在各個報文上打上標記序號及埠號轉發給網路層;然后,在網路層(IP 協議)增加作為通信目的地的 MAC 地址(ARP 協議)后轉發給鏈路層;最后接收端的服務器在鏈路層接收到資料,按序往上層發送,一直到應用層,

TCP 協議提供可靠的位元組流服務,并且為了更容易傳送大資料從而把資料分割,而且 TCP 協議能夠確認資料最終是否送達到對方(三次握手),
IP(Internet Protocol)協議的作用是把各種資料包傳送給對方,
ARP 是一種用以決議地址的協議,根據通信方的 IP 地址就可以反查出對應的 MAC 地址,
DNS 提供域名到 IP 地址之間的決議服務,
二、HTTP 協議結構
1.請求報文
請求報文是由請求方法、請求 URI、協議版本、可選的請求首部欄位和內容物體構成的,

keep-alive 表示只要客戶端或服務端任意一端沒有明確提出斷開連接,則保持 TCP 連接狀態,這樣不會導致每次的請求造成無謂的 TCP 連接建立和斷開,從而減少通信量的開銷和服務端的負載,也能使頁面的顯示速度顯著提高,
除了常見的 get/post 方法,HTTP/1.1 中還有諸多可使用的方法,
| HTTP 方法 | 作用 | 說明 |
|---|---|---|
| GET | 獲取資源 | 用來請求訪問已被 URI 識別的資源 |
| POST | 傳輸物體主體 | 用來傳輸物體的主體 |
| PUT | 傳輸檔案 | 自身不帶驗證機制,存在安全性問題 |
| HEAD | 獲得報文首部 | 不回傳報文主體部分,用于確認 URI 的有效性及資源更新的日期時間等 |
| DELETE | 洗掉檔案 | 自身不帶驗證機制,存在安全性問題 |
| OPTIONS | 詢問支持的方法 | 用來查詢針對請求 URI 指定的資源支持的方法 |
| TRACE | 追蹤路徑 | 容易引發 XST(Cross-Site Tracing, 跨站追蹤)攻擊,不建議使用 |
| CONNECT | 用隧道協議連接代理 | 代理服務器通信時建立隧道,實作用隧道協議進行 TCP 通信 |
TRACE 方法是讓 Web 服務器端將之前的請求通信環回給客戶端的方法,發送請求時,在 Max-Forwards 首部欄位中填入數值,每經過一個服務器端就將該數字減 1,當數值剛好減到 0 時, 就停止繼續傳輸,最后接收到請求的服務器端則回傳狀態碼 200 OK 的回應,
CONNECT 方法要求在與代理服務器通信時建立隧道,實作用隧道協議進行 TCP 通信,主要使用 SSL(Secure Sockets Layer,安全套接層)和 TLS(Transport Layer Security,傳輸層安全)協議把通信內容加密后經網路隧道傳輸給代理服務器,
2.回應報文
回應報文基本上由協議版本、狀態碼(表示請求成功或失敗的數字代碼)、用以解釋狀態碼的原因短語、可選的回應首部欄位以及物體主體構成,

回應狀態碼的類別:
| 狀態碼 | 類別 | 描述 |
|---|---|---|
| 1xx | Informational(資訊性狀態碼) | 接收的請求正在處理 |
| 2xx | Success(成功狀態碼) | 請求正常處理完畢 |
| 3xx | Redirection(重定向狀態碼) | 需要進行附加操作以完成請求 |
| 4xx | Client Error(客戶端錯誤狀態碼) | 服務器無法處理請求 |
| 5xx | Server Error(服務器錯誤狀態碼) | 服務器處理請求出錯 |
常見的回應狀態碼含義:
| 狀態碼 | 含義 | 描述 |
|---|---|---|
| 200 | OK | 請求正常處理并回應 |
| 204 | No Content | 請求正常處理,但在回傳的回應報文中不含物體的主體部分,客戶端不做更新 |
| 206 | Partial Content | 客戶端進行范圍請求,回應報文中由 Content-Range 指定范圍的物體內容 |
| 301 | Moved Permanently | 永久性重定向,回應報文中的 Location 首部欄位會帶回新的 URL 地址 |
| 302 | Found | 臨時性重定向,希望用戶(本次)能使用新的 URI 訪問 |
| 303 | See Other | 臨時性重定向,與 302 類似,但 303 狀態碼明確表示客戶端應當采用 GET 方法獲取資源 |
| 304 | Not Modified | 服務端判定資源沒有改變,不回應資源,客戶端可以從本地快取中獲取資源 |
| 400 | Bad Request | 客戶端請求報文中存在語法錯誤 |
| 401 | Unauthorized | 客戶端請求需要 HTTP 認證資訊 |
| 403 | Forbidden | 客戶端請求資源的訪問被服務器拒絕了,多見于權限問題 |
| 404 | Not Found | 服務器無法找到請求的資源 |
| 500 | Internal Server Error | 服務端執行請求時發生了錯誤 |
| 503 | Service Unavailable | 服務端暫時處于超負載或正在進行停機維護,現在無法處理請求 |
tips:當 301、302、303 回應狀態碼回傳時,幾乎所有的瀏覽器都會把 POST 改成 GET,并洗掉請求報文內的主體,之后請求會自動再次發送,
三、HTTP 狀態管理
HTTP 是一種不保存狀態,即無狀態(stateless)協議,HTTP 協議自身不對請求和回應之間的通信狀態進行保存,也就是說,每當有新的請求發送時,就會有對應的新回應產生,協議本身并不保留之前一切的請求或回應報文的資訊,這是為了更快地處理大量事務,確保協議的可伸縮性,以及減少服務器 CPU 和記憶體資源的損耗,從而特意把 HTTP 協議設計成如此簡單的,
那么 HTTP 協議怎么管理狀態呢?這就要說到 Cookie 技術,Cookie 技術通過在請求和回應報文中寫入 Cookie 資訊來控制客戶端的狀態,
Cookie 會根據從服務器端發送的回應報文內的一個叫做 Set-Cookie 的首部欄位資訊,通知客戶端保存 Cookie,當下次客戶端再往該服務器發送請求時,客戶端會自動在請求報文中加入 Cookie 值后發送出去,
服務器端發現客戶端發送過來的 Cookie 后,會去檢查究竟是從哪一個客戶端發來的連接請求,然后對比服務器上的記錄,最后得到之前的狀態資訊,
四、其他
1、HTTP 內容編碼是指在不丟失物體資訊的前提下所進行的壓縮,內容編碼后的物體由客戶端接收并負責解碼,常見的內容編碼有以下幾種:
- gzip(GUN zip)
- compress(UNIX 系統的標準壓縮)
- deflate(zlib)
- identity(不進行編碼)
2、HTTP 分塊傳輸編碼(Chunked Transfer Coding)會將物體主體分成多個部分(塊),每一塊都會用十六進制來標記塊的大小,而物體主體的最后一塊會使用“0(CR+LF)”來標記,分塊傳輸編碼的物體主體由客戶端接收并負責解碼,
3、HTTP 發送的一份報文主體中可含有多型別物體,通常是在圖片或文本檔案等上傳時使用,多型別物體的每個部分型別中,都可以含有首部欄位,多型別物體包含的物件如下:
- multipart/form-data,在 web 表單檔案上傳時使用,
- multipart/byteranges,狀態碼 206(Partial Content,部分內容)回應報文包含了多個范圍的內容時使用,
Content-Type: multipart/form-data; boundary=AaB03x
--AaB03x
Content-Disposition: form-data; name="field1"
Joe Blow
--AaB03x
Content-Disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain
...(file1.txt的資料) ...
--AaB03x
HTTP 協議的 header 中的 Range 是用來指定資源的 byte 范圍,比如:“Range:bytes=5001-10000” 表示請求 5001- 10000 位元組的資源,針對范圍請求,回應會回傳狀態碼為 206 Partial Content 的回應報文,并在 header 欄位指明 “ContentType:multipart/byteranges”
4、Comet 是一種高級的 Ajax 技術,通過延遲應答,模擬實作服務器端向客戶端推送(Server Push)的功能,通常,服務器端接收到請求,在處理完畢后就會立即回傳回應,但為了實作推送功能,Comet 會先將回應置于掛起狀態,當服務器端有內容更新時,再回傳該回應,因此,服務器端一旦有更新,就可以立即反饋給客戶端,
內容上雖然可以做到實時更新,但為了保留回應,一次連接的持續時間也變長了,期間,為了維持連接會消耗更多的資源,另外,Comet 也仍未解決 HTTP 協議本身存在的問題,
5、HTTP 協議的缺點?
- 一條連接上只可發送一個請求,
- 請求只能從客戶端開始,客戶端不可以接收除回應以外的指令,
- 請求/回應首部未經壓縮就發送,首部資訊越多延遲越大,
- 發送冗長的首部,每次互相發送相同的首部造成的浪費較多,
- 可任意選擇資料壓縮格式,非強制壓縮發送,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/187929.html
標籤:Java
