1. 請求報文(Request)
客戶端向服務器發(fā)起 HTTP 請求腾务,請求的報文結(jié)構如下:
GET /index.htm HTTP/1.1
Host: www.baidu.com
一開始的 GET 是請求方法(Request Method),/index.htm 表明要訪問的服務器上的文件,HTTP/1.1 表示 HTTP 的版本號勺卢,用來提示服務器客戶端所使用的 HTTP 協(xié)議版本抹恳。
通過 Chrome 的開發(fā)者工具妇斤,我們看一個比較復雜的請求茎截。這是百度登錄賬號的請求椎组。
與剛才不一樣的地方是油狂,這一次使用的請求方法(Request Method)是 POST。GET 與 POST 之間的區(qū)別有哪些?
網(wǎng)上公認的一些區(qū)別有下面這些专筷。(ps:有些區(qū)別其實在某種程度上來說算不上區(qū)別弱贼,看每個人的理解吧。)
- GET在瀏覽器回退時是無害的磷蛹,而POST會再次提交請求吮旅。
- GET產(chǎn)生的URL地址可以被Bookmark,而POST不可以味咳。
- GET請求會被瀏覽器主動cache鸟辅,而POST不會,除非手動設置莺葫。
- GET請求只能進行url編碼匪凉,而POST支持多種編碼方式。
- GET請求參數(shù)會被完整保留在瀏覽器歷史記錄里捺檬,而POST中的參數(shù)不會被保留再层。
- GET請求在URL中傳送的參數(shù)是有長度限制的,而POST么有堡纬。(URL 長度限制其實是與瀏覽器實現(xiàn)以及操作系統(tǒng)有關的聂受,HTTP 規(guī)范中并沒有對 URL 長度做限制。)
- 對參數(shù)的數(shù)據(jù)類型烤镐,GET只接受ASCII字符蛋济,而POST沒有限制。
- GET比POST更不安全炮叶,因為參數(shù)直接暴露在URL上碗旅,所以不能用來傳遞敏感信息。(這里的安全性比較镜悉,大家自行判斷吧祟辟,有些人可能會認為這兩者所謂的安全性并沒有什么區(qū)別。)
- GET參數(shù)通過URL傳遞侣肄,POST放在Request body中旧困。
其實在我看來,GET 與 POST 主要的區(qū)別還是在“語義”上稼锅。在 HTTP 規(guī)范中吼具,GET 主要用于信息的獲取,而不會對數(shù)據(jù)產(chǎn)生影響矩距,不會去增加或修改數(shù)據(jù)拗盒。而 POST 則主要用于向服務器傳輸數(shù)據(jù),增加或修改數(shù)據(jù)剩晴。這兩者在語義上存在根本的區(qū)別锣咒。在 RESTFul (一種后端 Web Service 的接口風格)風格的 API 中,GET 就表示獲取資源赞弥,POST 表示新增資源毅整。
2. 響應報文(Response)
3. HTTP 方法
GET:通常用于獲取資源。
POST:向服務器發(fā)送數(shù)據(jù)绽左,主要目的不是用于獲取響應內(nèi)容悼嫉。
PUT:傳輸文件(在 RESTful 架構中用于修改資源)。
DELETE:刪除文件拼窥。
OPTIONS:詢問支持的方法戏蔑。
HEAD:獲得響應的頭部,不返回 body鲁纠。
TRACE:追蹤路徑总棵,讓 Web 服務器端將之前的請求通信環(huán)回給客戶端的方法。
CONNECT:要求用隧道協(xié)議連接代理(連接代理時使用)
4. 持久連接
當瀏覽一個包含圖片及其他資源的 HTML 頁面時改含,除了請求 HTML 頁面情龄,還會請求頁面中的其他資源。而每次請求都會產(chǎn)生新的 TCP 連接建立和斷開捍壤,這增加了通信量骤视。HTTP/1.1 和 HTTP/1.0(沒有完全標準化)通過持久連接(HTTP Persistent Connections,也稱為 HTTP keep-alive 或 HTTP connection reuse)來解決這一問題鹃觉。持久連接的特點是专酗,只有在客戶端或服務器其中一方明確提出斷開連接的時候,才會斷開 TCP 連接盗扇。
5. 管線化(pipelining)
持久連接為管線化提供了基礎祷肯。管線化的意思是,不用等待上一個請求收到響應疗隶,就可以發(fā)送下一個請求躬柬,這樣就可以做到同時并行發(fā)送多個請求。
6. Cookie
HTTP 協(xié)議是無狀態(tài)的抽减,也就是說不對之前發(fā)生過的請求和響應信息進行保存及管理允青,這樣的優(yōu)點是可以減少服務器的 CPU 和內(nèi)存資源的消耗。
但是在有些時候卵沉,我們卻需要在一定程度上保存客戶端的狀態(tài)颠锉,例如用戶登錄之后獲取個人信息等,如果沒有一種機制來保存登錄狀態(tài)史汗,則需要每次發(fā)起 HTTP 請求時帶上用戶認證信息參數(shù)(例如用戶名密碼)琼掠。
為了解決這個問題,引入了 Cookie 技術停撞,Cookie 通過在請求頭及響應頭中附上信息來保存狀態(tài)瓷蛙。服務器可以在響應頭中附上名為 Set-Cookie 的字段悼瓮,來告知客戶端保存 Cookie(也就是頭部的這段信息)〖桠客戶端每次發(fā)起請求的時候横堡,則會自動在請求頭中附帶上保存的 Cookie 信息,服務器端則可以根據(jù)客戶端發(fā)來的 Cookie 信息來判斷客戶端狀態(tài)(例如判斷是否已經(jīng)登錄冠桃,以及登錄的用戶是誰)命贴。單純的 Cookie 模式只在客戶端上保存信息,而不在服務器端保存信息食听。
7. Session
一種更常見的模式是在服務器上保存信息胸蛛,也就是 Session 機制。當客戶端向服務器發(fā)起請求時樱报,服務器會在內(nèi)存中為該客戶端創(chuàng)建一塊區(qū)域葬项,用來存儲當前客戶端的一些信息,例如登錄狀態(tài)已經(jīng)用戶信息等迹蛤。并將 Session 對應的 Session Id (類似于鑰匙的概念玷室,通過 session id 可以查找到對應的 session 信息)以 Cookie 的形式發(fā)送給客戶端,客戶端就會將 Cookie 保存至本地笤受,每次請求帶上 Cookie穷缤,服務器端就可以通過 Cookie 中的 Session Id 來獲取客戶端的狀態(tài)。