1. 請求報文(Request)
客戶端向服務器發起 HTTP 請求,請求的報文結構如下:
GET /index.htm HTTP/1.1
Host: www.baidu.com
一開始的 GET 是請求方法(Request Method),/index.htm 表明要訪問的服務器上的文件,HTTP/1.1 表示 HTTP 的版本號,用來提示服務器客戶端所使用的 HTTP 協議版本。
通過 Chrome 的開發者工具,我們看一個比較復雜的請求。這是百度登錄賬號的請求。
與剛才不一樣的地方是,這一次使用的請求方法(Request Method)是 POST。GET 與 POST 之間的區別有哪些?
網上公認的一些區別有下面這些。(ps:有些區別其實在某種程度上來說算不上區別,看每個人的理解吧。)
- GET在瀏覽器回退時是無害的,而POST會再次提交請求。
- GET產生的URL地址可以被Bookmark,而POST不可以。
- GET請求會被瀏覽器主動cache,而POST不會,除非手動設置。
- GET請求只能進行url編碼,而POST支持多種編碼方式。
- GET請求參數會被完整保留在瀏覽器歷史記錄里,而POST中的參數不會被保留。
- GET請求在URL中傳送的參數是有長度限制的,而POST么有。(URL 長度限制其實是與瀏覽器實現以及操作系統有關的,HTTP 規范中并沒有對 URL 長度做限制。)
- 對參數的數據類型,GET只接受ASCII字符,而POST沒有限制。
- GET比POST更不安全,因為參數直接暴露在URL上,所以不能用來傳遞敏感信息。(這里的安全性比較,大家自行判斷吧,有些人可能會認為這兩者所謂的安全性并沒有什么區別。)
- GET參數通過URL傳遞,POST放在Request body中。
其實在我看來,GET 與 POST 主要的區別還是在“語義”上。在 HTTP 規范中,GET 主要用于信息的獲取,而不會對數據產生影響,不會去增加或修改數據。而 POST 則主要用于向服務器傳輸數據,增加或修改數據。這兩者在語義上存在根本的區別。在 RESTFul (一種后端 Web Service 的接口風格)風格的 API 中,GET 就表示獲取資源,POST 表示新增資源。
2. 響應報文(Response)
3. HTTP 方法
GET:通常用于獲取資源。
POST:向服務器發送數據,主要目的不是用于獲取響應內容。
PUT:傳輸文件(在 RESTful 架構中用于修改資源)。
DELETE:刪除文件。
OPTIONS:詢問支持的方法。
HEAD:獲得響應的頭部,不返回 body。
TRACE:追蹤路徑,讓 Web 服務器端將之前的請求通信環回給客戶端的方法。
CONNECT:要求用隧道協議連接代理(連接代理時使用)
4. 持久連接
當瀏覽一個包含圖片及其他資源的 HTML 頁面時,除了請求 HTML 頁面,還會請求頁面中的其他資源。而每次請求都會產生新的 TCP 連接建立和斷開,這增加了通信量。HTTP/1.1 和 HTTP/1.0(沒有完全標準化)通過持久連接(HTTP Persistent Connections,也稱為 HTTP keep-alive 或 HTTP connection reuse)來解決這一問題。持久連接的特點是,只有在客戶端或服務器其中一方明確提出斷開連接的時候,才會斷開 TCP 連接。
5. 管線化(pipelining)
持久連接為管線化提供了基礎。管線化的意思是,不用等待上一個請求收到響應,就可以發送下一個請求,這樣就可以做到同時并行發送多個請求。
6. Cookie
HTTP 協議是無狀態的,也就是說不對之前發生過的請求和響應信息進行保存及管理,這樣的優點是可以減少服務器的 CPU 和內存資源的消耗。
但是在有些時候,我們卻需要在一定程度上保存客戶端的狀態,例如用戶登錄之后獲取個人信息等,如果沒有一種機制來保存登錄狀態,則需要每次發起 HTTP 請求時帶上用戶認證信息參數(例如用戶名密碼)。
為了解決這個問題,引入了 Cookie 技術,Cookie 通過在請求頭及響應頭中附上信息來保存狀態。服務器可以在響應頭中附上名為 Set-Cookie 的字段,來告知客戶端保存 Cookie(也就是頭部的這段信息)。客戶端每次發起請求的時候,則會自動在請求頭中附帶上保存的 Cookie 信息,服務器端則可以根據客戶端發來的 Cookie 信息來判斷客戶端狀態(例如判斷是否已經登錄,以及登錄的用戶是誰)。單純的 Cookie 模式只在客戶端上保存信息,而不在服務器端保存信息。
7. Session
一種更常見的模式是在服務器上保存信息,也就是 Session 機制。當客戶端向服務器發起請求時,服務器會在內存中為該客戶端創建一塊區域,用來存儲當前客戶端的一些信息,例如登錄狀態已經用戶信息等。并將 Session 對應的 Session Id (類似于鑰匙的概念,通過 session id 可以查找到對應的 session 信息)以 Cookie 的形式發送給客戶端,客戶端就會將 Cookie 保存至本地,每次請求帶上 Cookie,服務器端就可以通過 Cookie 中的 Session Id 來獲取客戶端的狀態。