HTTP 協議簡介
瀏覽器工作的第一步是通過HTTP請求,根據URL 訪問服務器獲取數據(建立http請求之前還需要 DNS 查詢)。
HTTP是一種應用層的協議,是一個純文本的協議,規(guī)定了必須是基于 TCP 協議(傳輸層)的,TCP 協議是一條雙向的通訊通道,HTTP 在 TCP 的基礎上,規(guī)定了 Request-Response 的模式。這個模式決定了通訊必定是由瀏覽器端首先發(fā)起的。
HTTP是一種無狀態(tài)的協議,無狀態(tài)是指Web瀏覽器和Web服務器之間不需要建立持久的連接,這意味著當一個客戶端向服務器端發(fā)出請求,然后Web服務器返回響應(response),連接就被關閉了,在服務器端不保留連接的有關信息。
HTTP請求過程
HTTP通信機制是在一次完整的HTTP通信過程中,Web瀏覽器與Web服務器之間將完成下列7個步驟:
(1)建立TCP連接
在HTTP工作開始之前,Web瀏覽器首先要通過網絡與Web服務器建立連接,該連接是通過TCP來完成的,該協議與IP協議共同構建Internet,即著名的TCP/IP協議族,因此Internet又被稱作是TCP/IP網絡。HTTP是比TCP更高層次的應用層協議,根據規(guī)則,只有低層協議建立之后才能,才能進行更層協議的連接,因此,首先要建立TCP連接,一般TCP連接的端口號是80
(2)Web瀏覽器向Web服務器發(fā)送請求命令
一旦建立了TCP連接,Web瀏覽器就會向Web服務器發(fā)送請求命令
例如:GET/sample/hello.jsp HTTP/1.1
(3)Web瀏覽器發(fā)送請求頭信息
瀏覽器發(fā)送其請求命令之后,還要以頭信息的形式向Web服務器發(fā)送一些別的信息,之后瀏覽器發(fā)送了一空白行來通知服務器,它已經結束了該頭信息的發(fā)送。
(4)Web服務器應答
客戶機向服務器發(fā)出請求后,服務器會客戶機回送應答,
HTTP/1.1 200 OK
應答的第一部分是協議的版本號和應答狀態(tài)碼
(5)Web服務器發(fā)送應答頭信息
正如客戶端會隨同請求發(fā)送關于自身的信息一樣,服務器也會隨同應答向用戶發(fā)送關于它自己的數據及被請求的文檔。
(6)Web服務器向瀏覽器發(fā)送數據
Web服務器向瀏覽器發(fā)送頭信息后,它會發(fā)送一個空白行來表示頭信息的發(fā)送到此為結束,接著,它就以Content-Type應答頭信息所描述的格式發(fā)送用戶所請求的實際數據
(7)Web服務器關閉TCP連接
一般情況下,一旦Web服務器向瀏覽器發(fā)送了請求數據,它就要關閉TCP連接,然后如果瀏覽器或者服務器在其頭信息加入了這行代碼
Connection:keep-alive
TCP連接在發(fā)送后將仍然保持打開狀態(tài),于是,瀏覽器可以繼續(xù)通過相同的連接發(fā)送請求。保持連接節(jié)省了為每個請求建立新連接所需的時間,還節(jié)約了網絡帶寬。
HTTP 協議格式

一,HTTP請求
下面是一個HTTP請求的例子:
GET /sample.jsp HTTP/1.1
Accept:image/gif.image/jpeg,*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate? ? ? ? ? ? ? ? ? ? ? ? ?
username=jinqiao&password=1234
1.request line
第一行被稱作 request line,它分為三個部分,請求的“方法”、請求的路徑、請求的協議和版本。
request line 里面的方法跟我們編程中的方法意義類似,表示我們此次 HTTP 請求希望執(zhí)行的操作類型。方法有以下幾種定義:
GET,POST,HEAD,PUT,DELETE,CONNECT,OPTIONS,TRACE
瀏覽器通過地址欄訪問頁面都是 GET 方法。表單提交產生 POST 方法。
HEAD 則是跟 GET 類似,只返回請求頭,多數由 JavaScript 發(fā)起
PUT 和 DELETE 分別表示添加資源和刪除資源,但是實際上這只是語義上的一種約定,并沒有強約束。
CONNECT 現在多用于 HTTPS 和 WebSocket。
OPTIONS 和 TRACE 一般用于調試,多數線上服務都不支持。
GET方法 VS POST方法
GET方法是默認的HTTP請求方法,我們日常用GET方法來提交表單數據,然而用GET方法提交的表單數據只經過了簡單的編碼,同時它將作為URL的一部分向Web服務器發(fā)送,因此,如果使用GET方法來提交表單數據就存在著安全隱患上。例如
Http://127.0.0.1/login.jsp?Name=zhangshi&Age=30&Submit=%cc%E+%BD%BB
從上面的URL請求中,很容易就可以辯認出表單提交的內容。(?之后的內容)另外由于GET方法提交的數據是作為URL請求的一部分,所以提交的數據量不能太大。
POST方法是GET方法的一個替代方法,它主要是向Web服務器提交表單數據,尤其是大批量的數據。POST方法克服了GET方法的一些缺點。通過POST方法提交表單數據時,數據不是作為URL請求的一部分而是作為標準數據傳送給Web服務器,這就克服了GET方法中的信息無法保密和數據量太小的缺點。因此,出于安全的考慮以及對用戶隱私的尊重,通常表單提交時采用POST方法。
2.Request Header (HTTP 頭)
request line后面是請求頭。由若干行組成,每行是用冒號分隔的名稱和值。是鍵值對的格式。

3.HTTP Request Body(正文)
請求頭和請求正文之間是一個空行,這個行非常重要,它表示請求頭已經結束。
接下來的是請求正文。請求正文中可以包含客戶提交的查詢字符串,文件或者表單數據。
一些常見的 body 格式是:
application/json
application/x-www-form-urlencoded
multipart/form-data
text/xml
我們使用 html 的 form 標簽提交產生的 html 請求,默認會產生 application/x-www-form-urlencoded 的數據格式,當有文件上傳時,則會使用 multipart/form-data。
二,HTTP響應
HTTP響應與HTTP請求相似,HTTP響應也由3個部分構成。
下面是一個HTTP響應的例子:
HTTP/1.1 200 OK
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:23:42 GMT
Content-Length:112
<html>
<head>
<title>HTTP響應示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>
1.response line
第一行被稱作 response line,它也分為三個部分,協議和版本、狀態(tài)碼和狀態(tài)文本。
常見的狀態(tài)碼有以下幾種。
1xx:臨時回應,表示客戶端請繼續(xù)。
2xx:請求成功。
200:請求成功。
3xx: 表示請求的目標有變化,希望客戶端進一步處理。
301&302:永久性與臨時性跳轉。
304:跟客戶端緩存沒有更新。
4xx:客戶端請求錯誤。
403:無權限。
404:表示請求的頁面不存在。
5xx:服務端請求錯誤。
500:服務端錯誤。
503:服務端暫時性錯誤,可以一會再試。
2.Response Header
緊隨在 response line 之后,是響應頭,每行是用冒號分隔的名稱和值。

3.HTTP Response Body
在頭之后,以一個空行為分隔,是 /響應體,內容是 html 代碼。
HTTPS
在 HTTP 協議的基礎上,HTTPS 和 HTTP2 規(guī)定了更復雜的內容,但是它基本保持了 HTTP 的設計思想,即:使用上的 Request-Response 模式。
HTTPS 有兩個作用,一是確定請求的目標服務端身份,二是保證傳輸的數據不會被網絡中間節(jié)點竊聽或者篡改。
HTTPS 是使用加密通道來傳輸 HTTP 的內容。但是 HTTPS 首先與服務端建立一條 TLS 加密通道。TLS 構建于 TCP 協議之上,它實際上是對傳輸的內容做一次加密,所以從傳輸內容上看,HTTPS 跟 HTTP 沒有任何區(qū)別。
HTTP 2
HTTP 2 是 HTTP 1.1 的升級版本。
HTTP 2.0 最大的改進有兩點,一是支持服務端推送,二是支持 TCP 連接復用。
服務端推送能夠在客戶端發(fā)送第一個請求到服務端時,提前把一部分內容推送給客戶端,放入緩存當中,這可以避免客戶端請求順序帶來的并行度不高,從而導致的性能問題。
TCP 連接復用,則使用同一個 TCP 連接來傳輸多個 HTTP 請求,避免了 TCP 連接建立時的三次握手開銷,和初建 TCP 連接時傳輸窗口小的問題。