超文本傳輸協議(英語:HyperText Transfer Protocol,縮寫:HTTP)是一種用於分佈式、協做式和超媒體信息系統的應用層協議。HTTP 是 WWW 萬維網通訊的基礎,被普遍使用,最多見的當你瀏覽一個網頁時,瀏覽器和服務器之間就會經過 HTTP 進行數據的發送和接收。因此 HTTP 是一種基於請求/響應的協議。css
根據 HTTP 的協議版本,發展歷程大體分爲:HTTP/0.9
、HTTP/1.0
、HTTP/1.1
、 HTTP/2.0
和 HTTP/3.0
。其中 HTTP/1.1
版本是使用最普遍的協議。html
HTTP/0.9linux
最先版本是 1991 年發佈的 0.9 版。該版本極其簡單,只有一個命令GET
。沒有 Header
等描述信息,服務器發送完畢,即關閉 TCP
鏈接。nginx
HTTP/1.0web
1996 年 5 月,HTTP/1.0 版本發佈,內容大大增長。增長了不少指令,好比增長了 POST
指令,其餘的新增功能還包括狀態碼(status code)、多字符集支持、多部分發送(multi-part type)、權限(authorization)、緩存(cache)、內容編碼(content encoding)等。json
HTTP/1.1瀏覽器
因爲 HTTP1.0
協議中每一個 TCP
只能發送一個請求,請求完畢後鏈接就關閉。形成 TCP
新建鏈接成本比較搞。因此 1997 年 1 月,HTTP/1.1
版本發佈,只比 1.0 版本晚了半年。它進一步完善了 HTTP
協議,一直用到了20年後的今天,直到如今仍是最流行的版本。緩存
主要增長了持久化鏈接、管道機制。引入了持久鏈接(persistent connection),即 TCP
鏈接默認不關閉,能夠被多個請求複用,不用聲明Connection: keep-alive
。管道機制(pipelining),即在同一個 TCP
鏈接裏面,客戶端能夠同時發送多個請求。這樣就進一步改進了 HTTP
協議的效率。安全
HTTP/2.0服務器
該版本的特色是:
HTTP/1.1
版本中,支持文本和二進制的數據體,在 HTTP/2.0
中則是一個完全的二進制協議,頭信息和數據體都是二進制,而且統稱爲"幀"(frame):頭信息幀和數據幀。二進制協議的一個好處是,能夠定義額外的幀。HTTP/3.0
在 HTTP/3.0
中爲提升 Web 應用性能,HTTP/3.0 將 TCP 協議更換爲基於 UDP 的谷歌 QUIC`。更多的內容能夠參照這其它文章瞭解。
Uniform Resource Locator
全稱統一資源定位符,簡稱 URL
。用於惟一標識網絡上的資源,它是 WWW 的統一資源定位標誌,就是指網絡地址。
URL 基本格式
通用的格式:scheme://host[:port#]/path/…/[?query-string] [#anchor]
名稱 | 功能 |
---|---|
scheme | 傳送協議,常見的有:http、https、ftp |
// | 層級 URL 標記符號,固定不變 |
host | 服務器,一般爲域名或 ip |
port | 端口號 |
path | 資源路徑 |
query-string | 發給服務器的查詢參數 |
anchor | 片斷、錨點,以「#」字符爲起點 |
舉個例子,URL = www.andoter.com:80/news/index.…
一個 HTTP
請求報文的通常格式由請求行、請求頭部和請求數據組成。
請求行由三部分組成:請求方法、URL、協議版本。
GET /img/bd_logo1.png?qua=high&where=super HTTP/1.1
Referer: https://www.baidu.com/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
Sec-Fetch-Dest: image
複製代碼
在上面的示例中:
在 HTTP/1.1
版本中定義了常見的一組請求方法。
方法名 | 功能 |
---|---|
GET |
GET 方法請求一個指定資源的表示形式. 使用 GET 的請求應該只被用於獲取數據。 |
HEAD |
HEAD 方法請求一個與 GET 請求的響應相同的響應,但沒有響應體。 |
POST |
POST 方法用於將實體提交到指定的資源,一般致使在服務器上的狀態變化或反作用。 |
PUT |
PUT 方法用請求替換目標資源的全部當前表示。 |
DELETE |
DELETE 方法刪除指定的資源。 |
CONNECT |
CONNECT 方法創建一個到由目標資源標識的服務器的隧道。 |
OPTIONS |
OPTIONS 方法用於描述目標資源的通訊選項。 |
TRACE |
TRACE 方法沿着到目標資源的路徑執行一個消息環回測試。 |
PATCH |
PATCH 方法用於對資源應用部分修改。 |
雖然 HTTP
的請求方式有多種,可是咱們在實際應用中經常使用的也就是 GET
和 POST
,其餘請求方式也均可以經過這兩種方式間接的來實現。
請求頭部一般用於添加一些附加信息,格式爲KV 鍵值對—鍵: 值
,注意冒號後面有一個空格。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive
Cookie:
Host: www.baidu.com
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
複製代碼
常見的請求頭。
名稱 | 功能 |
---|---|
Accept |
瀏覽器可接受的 MIME 類型,能夠多個值,用, (英文逗號)分開 |
Accept-Encoding |
瀏覽器可以進行解碼的數據編碼方式,好比 gzip |
Accept-Charset |
瀏覽器可接受的字符集 |
Accept-Language |
瀏覽器所但願的語言種類,當服務器可以提供一種以上的語言版本時要用到 |
Authorization |
受權信息,用於設置身份認證信息 |
Connection |
表示是否須要持久鏈接。若是 Servlet 看到這裏的值爲 Keep-Alive ,或者看到請求使用的是 HTTP 1.1 (默認進行持久鏈接),它就能夠利用持久鏈接的優勢。 |
Content-Type |
MediaType ,便是 Internet Media Type ,互聯網媒體類型;也叫作 MIME 類型,在 http 協議消息頭中,使用 Content-Type 來表示具體請求中的媒體類型信息。常見的類型。 |
Content-Length |
表示請求消息正文的長度 |
Cookie |
Cookie 信息 |
Host |
請求的主機和端口號 |
If-Modified-Since |
只有當所請求的內容在指定的日期以後又通過修改才返回它,不然返回 304 「Not Modified」 應答。 |
Referer |
標識請求引用自哪一個地址,好比你從頁面 A 跳轉到頁面 B 時,值爲頁面 A 的地址 |
User-Agent |
瀏覽器類型 |
Cache-Control |
指定請求和響應遵循的緩存機制,請求時的緩存指令包括 no-cache 、no-store 、max-age 、max-stale 、min-fresh 、only-if-cached |
請求體主要是針對 POST
請求而言,根據不一樣的應用場景,常見的 POST
請求提交的數據類型有如下 3 種。
application/json
最多見的類型,愈來愈多的應用使用 application/json
,用來告訴服務端消息主體是序列化的 json
字符串。
multipart/form-data
將表單的數據處理爲一條消息,以標籤爲單元,用分隔符分開。既能夠上傳鍵值對,也能夠上傳文件。必須讓 form
表單的 enctype
等於 multipart/form-data
。
application/x-www-form-urlencoded
瀏覽器的原生 form
表單,若是不設置 enctype
屬性,那麼最終就會以 application/x-www-form-urlencoded
方式提交數。
一個 HTTP
影響消息由響應狀態行、影響頭、空行和響應正文組成。
狀態行由:協議版本、狀態碼、狀態碼描述組成。
HTTP/1.1 200 OK
Server: nginx/1.10.2
Date: Mon, 02 Mar 2020 15:23:27 GMT
Content-Type: application/json
複製代碼
上面的例子中:
常見的狀態碼有:
狀態碼 | 功能描述 |
---|---|
1XX (提示信息) | 表示請求已接收,繼續處理 |
2XX (成功) | 表示請求已被成功接收、理解、接收 |
3XX (重定向) | 表示資源(網頁等)被永久轉移到其它 URL,也就是所謂的重定向 |
4XX (客戶端錯誤) | 表示請求有語法錯誤或者請求沒法實現 |
5XX (服務器錯誤) | 表示服務器未能實現合法的請求 |
響應頭部一樣是鍵值對的形式。
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type,X-Agent,X-Token,X-Legacy-Token,X-Legacy-Uid,X-Legacy-Device-Id,X-Legacy-New-Token,X-Request-Id
Access-Control-Allow-Methods: GET, PUT, POST, DELETE, PATCH
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 86400
Connection: close
Content-Encoding: gzip
Content-Type: application/json
Date: Mon, 02 Mar 2020 15:23:27 GMT
Server: nginx/1.10.2
Set-Cookie: QINGCLOUDELB=6c217b5deeccb67c0d51e4d6f319ad279a8d3a749e334706eff5b9d6e96d83ee|Xl0k8|Xl0k8; path=/; HttpOnly
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Request-Id: c3d8f9f05c9911eab9dd8f862fae4482
複製代碼
響應頭部和請求頭部通用的 Header
有:Accept
、Content-length
、Content-Type
、Content-Encoding
等。響應頭部特殊的 Header
有:
名稱 | 功能描述 |
---|---|
Connection |
針對該連接的全部預期的選項 |
Date |
此條消息被髮送時的日期和時間 |
Expires |
指定一個日期/時間,超過該時間此迴應過時 |
Last-Modified |
請求對象的最後修改時間 |
Server |
服務器名稱 |
Vary |
告知下游的代理服務器如何對以後的請求協議頭進行匹配,以決定是否可以使用已緩存的響應內容而不是從新從原服務器請求新的內容 |
響應體就是響應的消息體,若是是純數據就是返回純數據,若是請求的是HTML頁面,那麼返回的就是 HTML
代碼,若是是 JS
就是 JS
代碼,如此之類。
在進行網絡請求流程分析是,咱們能夠先了解下 OSI
模型。OSI
的全程是Open Systems Interconncection,即開放系統互聯,它由ISO(International Organization for Standardization)制定。OSI是網絡通訊的一種通用框架,它分爲七層,而且定義了在每一層上數據的處理方法。
OSI 七層網絡模型:
這裏借用博客深刻淺出-網絡七層模型中的一張圖來更詳細瞭解下。
當咱們在瀏覽器中輸入 https://www.baidu.com
點擊 Enter
後瀏覽器給咱們展示百度的首頁,那這中間發生了哪些過程,最終給咱們展示出一個渲染好的網頁。大體的過程能夠歸納爲以下:
www.baidu.com
這個網址進行 DNS
域名解析,獲得對應的 IP
地址IP
,找到對應的服務器,發起 TCP
的三次握手TCP
鏈接後發起 HTTP
請求HTTP
請求,瀏覽器獲得 html
代碼html
代碼,並請求 html
代碼中的資源(如 js、css
圖片等)在這個過程當中,有兩個常見的概念:DNS 解析
和 TCP 的三次握手
。
DNS(Domain Name System)
,翻譯過來就是域名和 IP
地址相互映射的系統。這裏又能夠細分爲:權威 DNS、遞歸 DNS(又稱爲 Local DNS) 和 公共 DNS。
DNS 解析過程
Local DNS
發起 www.baidu.com
的訪問請求Local DNS
收到請求後,從 Root Hints
獲取根域名服務器地址,並向 Root DNS Server
發起解析請求,Root DNS Server
返回 com
頂級域名服務器 IP
地址Local DNS
向 COM DNS Server
發起域名解析請求,COM DNS Server
返回 .com
二級域名服務器 IP
地址Local DNS
向 百度 DNS Server
發起域名解析請求,CSDN DNS Server
返回最終的 www.baidu.com
的 IP
地址Local DNS
將遞歸查詢獲取的 IP
地址返回給終端基於前面的知識,在傳輸層和網絡層中,常見的是採用 TCP/IP
的協議進行通訊,TCP
協議提供可靠的鏈接服務,採用三次握手創建一個可靠鏈接。
這裏須要瞭解 TCP
報文格式中的 6 中標誌位:
三次握手
所謂三次握手(Three-Way Handshake)就是指創建一個 TCP
鏈接時,須要客戶端和服務端總共發送 3 個包以確認鏈接的創建。
第一次握手:Client
將標誌位 SYN
置爲 1,隨機產生一個值 seq=J
,並將該數據包發送給 Server
,Client
進入 SYN_SENT
狀態,等待 Server
確認。
第二次握手:Server
收到數據包後由標誌位 SYN=1
知道 Client
請求創建鏈接,Server
將標誌位 SYN
和 ACK
都置爲 1,ack=J+1
,隨機產生一個值 seq=K
,並將該數據包發送給 Client
以確認鏈接請求,Server
進入 SYN_RCVD
狀態。
第三次握手:Client
收到確認後,檢查 ack
是否爲 J+1
,ACK
是否爲 1,若是正確則將標誌位 ACK
置爲 1,ack=K+1
,並將該數據包發送給 Server
,Server
檢查 ack
是否爲 K+1
,ACK
是否爲 1,若是正確則鏈接創建成功,Client
和 Server
進入 ESTABLISHED
狀態,完成三次握手,隨後 Client
與 Server
之間能夠開始傳輸數據了。
四次揮手
所謂四次揮手(Four-Way Wavehand)就是指斷開一個 TCP
鏈接時,須要客戶端和服務端總共發送 4 個包以確認鏈接的斷開。
第一次揮手:Client
發送一個 FIN
,用來關閉 Client
到 Server
的數據傳送,Client
進入 FIN_WAIT_1
狀態。 第二次揮手:Server
收到 FIN
後,發送一個 ACK
給 Client
,確認序號爲收到序號+1(與 SYN
相同,一個 FIN
佔用一個序號),Server
進入 CLOSE_WAIT
狀態。 第三次揮手:Server
發送一個 FIN
,用來關閉 Server
到 Client
的數據傳送,Server
進入 LAST_ACK
狀態。 第四次揮手:Client
收到 FIN
後,Client
進入 TIME_WAIT
狀態,接着發送一個 ACK
給 Server
,確認序號爲收到序號+1,Server
進入 CLOSED
狀態,完成四次揮手。
IPv4
是英語Internet Protocol version 4
的縮寫,又稱互聯網通訊協議第四版。支持的 IP
地址數量:2^32(約 4×10^9)。IPv6
是英文 Internet Protocol Version 6
即互聯網協議第6版的縮寫,對 IPv4
進行數量上的擴充,支持地址數量:2^128(約3.4×10^38)。
更多文章:
TCP
是面向鏈接的可靠字節流傳輸,在數據傳輸前經過三次握手創建鏈接,而且提供超時重發,丟棄重複數據,檢驗數據,流量控制等功能,保證數據能從一端傳到另外一端。缺點是效率低,佔用資源。
UDP
面向非鏈接不可靠的字節流傳輸,可是速度快、比 TCP
稍微安全。佔用資源相對較少。適用於對網絡通信質量要求不高的時候,要求網絡通信速度能儘可能的快,好比長視頻流。
參照連接