一、HTTP超文本傳輸協(xié)議
? ?HTTP
全稱為Hyper Text Transfer Protocol
超文本傳輸協(xié)議,它是基于TCP
傳輸協(xié)議構建的應用層協(xié)議,作為支撐萬維網www
的核心協(xié)議,為了保證其效率及處理大量事務的能力,因此在設計時,HTTP
被制定成為一種無狀態(tài)協(xié)議,也就是說:HTTP
本身不會對發(fā)送過的請求和相應的通信狀態(tài)進行持久化處理。
也正因
HTTP
的無狀態(tài)特征,所以在有些需要保持狀態(tài)的場景中,則需要引入其他技術來實現(xiàn),比如需要保持“登錄狀態(tài)、授權狀態(tài)”時,需要配合Cookie
來實現(xiàn)記錄與管理狀態(tài)。
HTTP
于1990年提出后,經過多年的完善和擴展,目前已經存在多個主流版本的迭代:
目前HTTP
主流應用版本還是HTTP/1.1、2.0
。
1.1、HTTP協(xié)議工作流程
? ?HTTP
核心由請求與響應構成,是一種典型基于客戶端和服務器模型的協(xié)議,在目前的網絡中,瀏覽器作為HTTP
協(xié)議的主要載體,一般來說,“從瀏覽器發(fā)出請求到服務器返回響應”,這個過程被稱為一次HTTP
操作,也被稱為一個事務,其具體過程如下:
- ①客戶端連接
WEB
服務器:瀏覽器與服務器的HTTP/80
端口建立一個套接字連接。 - ②發(fā)送
HTTP
請求:根據用戶的URL
,通過套接字連接向服務器發(fā)送對應的請求報文。 - ③服務器處理請求并返回響應結果:解析請求、定位資源、執(zhí)行邏輯后將結果寫到套接字,客戶端從套接字中獲取結果。
- ④釋放
TCP
套接字連接:默認情況下,服務器主動終止套接字連接,客戶端被動關閉。
從建立連接發(fā)出請求,到服務器處理完成后,返回響應再關閉連接,既代表著一個“事務”就完成了,但客戶端接受到響應后,還會存在:解析響應報文、渲染結果數據這兩步操作。
接下來我們根據
HTTP
工作流程的先后順序,依次拉開HTTP
協(xié)議的完整序幕,如下:
- ①、URI資源標識符及URL資源定位符詳解
- ②、
HTTP
報文-請求報文與響應報文 - ③、
HTTP
請求方法分類 - ④、
HTTP
請求狀態(tài)碼 - .......
1.2、URI資源標識符及URL資源定位符
? ?一般網絡請求的前提是:需要用戶在瀏覽器輸入或點擊超鏈接后,得到一個目標網址才會觸發(fā),而網址的專業(yè)術語為:URL
統(tǒng)一資源定位符,而URL
又是URI
的一部分。
但URI
統(tǒng)一資源標識符這個詞并沒有URL
那么普及,因此出現(xiàn)在大眾視野中的次數并不多,它的作用是區(qū)分網絡上不同的資源,主要涵蓋了URL
和URN
兩部分。
接下來看看URL
的構成,一般來說完整的URL
結構如下:
但上述結構使用較少,URL
的常用結構如下:
我們依次分析看看:
-
scheme
:表示使用的協(xié)議類型,例如http、https、ftp、chrome
等。 -
://
:協(xié)議類型與后續(xù)描述符之間的分隔符。 -
domainName
:網站域名,經DNS
解析后會得到具體服務器IP
。 -
/path
:請求路徑,代表客戶端請求的資源所在位置,不同層級目錄之間用/
區(qū)分。 -
?query1=value
:請求參數,?
后面表示請求的參數,采用K-V
鍵值對形式。 -
&query2=value
:多個請求參數,不同的參數之間用&
分割。 -
#fragment
:表示所定位資源的一個錨點,瀏覽器可根據這個錨點跳轉對應的資源位置。
PS:錨點也被成為片段標識符,
#
部分之后的內容,即錨點不會被發(fā)送到服務器,錨點的作用僅是在瀏覽器解析時,跳轉指定的位置顯示。
對比完整的URL
,常用的URL
中除開用戶名及密碼外,還存在一點不同,即host:port
主機IP+端口變?yōu)榱?code>domainName域名,那為什么又要這樣做呢?
①
IP
不方便記憶,對于普通用戶而言,一串數字遠比不了“拼音縮寫”,好比www.baidu.com
任何人都能記住,但14.215.177.38
卻不行。
②服務器的IP
是動態(tài)多變,當網關宕機后換機部署時,IP
又不相同了,但域名卻是固定的,就算服務器IP
再怎么變,域名都不會更換。
用戶請求的域名又是如何變成具體IP
的呢?這里面就得提及另一個概念:DNS
解析。
1.2.1、DNS域名解析系統(tǒng)
? ?在計算機網絡中,每個主機都存在一個IP
地址,但由于IP
是一串數字不方便人類記憶,因此出現(xiàn)了一種協(xié)議名為DNS
,它可以把生澀的IP
地址轉換為便于人類記憶的域名,例如百度的:www.baidu.com
。
? ?DNS(Domain Name System)
中文的意思是域名系統(tǒng),每個互聯(lián)網企業(yè)WEB
網站都可以看作是它自己在網上的門戶,那么每個網站的域名就類似于“門牌號”,通常情況下,為了方便正常人記憶,域名都會使用公司的名稱或簡稱,例如www.taobao.com、www.baidu.com、www.jd.com
等,因此當你要訪問一個Web
網站,但又不知道其確切域名時,那么你首先可以輸入其公司名稱試試看。
趣事:因為一個公司域名大部分情況下都是由其名稱或簡稱構成,因此有些人會大量注冊域名,然后再高價轉賣給這些公司,以此牟利。比如美圖秀秀的
Boss
蔡文勝,就以轉賣域名為起點,從而躍身百億富豪。
因特網最開始僅由幾百臺計算機組成,因此最初的域名與IP
映射關系都是被保存在本地的Hosts.txt
文件中,每臺因特網中的機器都從服務器上下載Hosts
文件,然后發(fā)送請求時就從本地查詢IP
信息,但隨著接入因特網的設備越來越多,因此原有的這種方式無法滿足日益增長的因特網需求。
畢竟全球的設備都在不斷的接入因特網,上網時都在使用域名訪問,不過世界上并不存在一臺DNS
服務器可以映射所有的IP
,所以域名系統(tǒng)最終被設計成了一個:帶有層次結構的分布式K-V
數據庫,整個DNS
由很多服務器共同組成的,大體結構如下:
PS:比如
www.baidu.com
,實際上完整的域名為:www.baidu.com.
,根域則是最后的.
,系統(tǒng)做了兼容,不需要用戶手動寫出。
因特網上的域名服務系統(tǒng)也是按照域名的層次來劃分的,每一個域名服務器都只對域名體系中的一部分進行管轄,DNS
服務器主要分為三類:
- ①根域名服務器
- ②
TLD
頂級域名服務器 - ③授權域名(子域)服務器
除此之外,還存在一種本地DNS
服務器,但這個并不歸納在域名系統(tǒng)的分層結構中,不過本地DNS
服務器卻是DNS
至關重要的一環(huán)。
DNS域名查詢
DNS
中主要分為遞歸查詢、迭代查詢兩種方式:
- ①全遞歸查詢:
遞歸查詢的意思是指:客戶端只需發(fā)出一次請求,就能得到相應的解析結果。
- ②先遞歸+后迭代查詢:
迭代查詢的意思是指:客戶端需經過多次請求查詢,才能得到相應的解析結果。
當然,上述過程無論是迭代還是遞歸查詢,對于上層DNS
服務器而言,全球的訪問壓力都足以讓其癱瘓,因此DNS
中還存在一個重要的概念:DNS
緩存:
- 本地
DNS
/非授權服務器緩存:各大運營商或大公司都有自己的DNS
服務器,一般部署在距離用戶較近地方,代替用戶訪問核心DNS
系統(tǒng),同時這些DNS
服務器可以緩存之前的查詢結果,下次出現(xiàn)相同的DNS
解析請求時,可直接返回已緩存的IP
。 - 本地計算機
DNS
緩存:計算機本地緩存主要分為操作系統(tǒng)緩存與瀏覽器緩存兩種:- 瀏覽器緩存一般會有時間限制,如
Chrome
瀏覽器默認是1min
,一分鐘內請求該域名,都會直接從本地緩存中獲取IP
。 - 操作系統(tǒng)緩存是指本地的
hosts
文件,在瀏覽器中無法獲取映射IP
時,會嘗試從hosts
文件中獲取。
- 瀏覽器緩存一般會有時間限制,如
注意:主機和本地域名服務器之間的查詢方式是遞歸查詢,本地域名服務器和其他域名服務器之間的查詢方式是迭代查詢,防止根域名服務器壓力過大,也就是代表著:一般情況下
DNS
解析請求都采用先遞歸+后迭代方式。
當用戶在瀏覽器向一個域名發(fā)出請求后,DNS
解析請求具體查詢過程如下:
- ①客戶端輸入域名準備訪問網站。
- ②先查詢「瀏覽器的
DNS
緩存」,命中直接向IP
發(fā)起訪問,未命中繼續(xù)往下。 - ③繼續(xù)查詢「
OS
的hosts
文件」,如果仍然未命中,則向「本地域名服務器」發(fā)起「遞歸查詢」請求。 - ④「本地域名服務器」先查詢自身緩存,未命中則向「根域名服務器」進行「迭代查詢」:
- A.「根域名服務器」返回「頂級域名服務器」的地址
- B.「本地域名服務器」再根據地址向「頂級域名服務器」發(fā)起查詢
- C.「頂級域名服務器」返回負責該「域名」的「授權域名服務器」地址
- D.「本地域名服務器」再根據地址向「授權域名服務器」發(fā)起查詢
- E.「授權域名服務器」返回「域名」的具體
IP
地址
- ⑤「本地域名服務器」將
IP
返回給客戶端并將「域名/IP
映射」緩存起來。 - ⑥「瀏覽器」得到
IP
后,向其發(fā)出具體的「用戶請求」,并將「域名/IP
映射」緩存。
至此URL
這塊的內容已經分析明白了,接著繼續(xù)往下看看。
1.3、HTTP報文的組成結構
? ?瀏覽器訪問服務器的過程中,解析域名得到具體IP
后,會將用戶的請求組裝成HTTP
報文,HTTP
報文主要分為請求報文與應答(響應)報文兩類。
1.3.1、請求報文
? ?用戶請求服務器時,發(fā)送的報文被稱為請求報文,大體結構如下:
請求報文主要由請求行、請求頭、空行、請求主體四部分組成。
請求行
請求行也被稱為起始行,主要包含請求方法、資源路徑以及協(xié)議版本三部分,具體如下:
GET /index.html HTTP/1.1
注意:報文中每個不同的部位之間必須要用SP
空格隔開,末尾需要有一個CRLF
回車換行符,遵循ABNF
語法規(guī)范。
請求頭
不管是請求頭亦或是響應頭,都可以算是HTTP
報文中最復雜的內容,因為其中可選字段是非常多的,一般來說頭部字段遵循如下規(guī)范:
- 每個字段名與字段值以
K-V
鍵值對形式傳遞。 - 字段名不區(qū)分字母的大小寫。
- 字段名中不允許出現(xiàn)非法字符,如空格、
/、&、^、_、@、}.....
- 字段名與字段值之間必須以
:
分割。
后續(xù)《
HTTP
報文字段》章節(jié)再詳細分析。
空行
必須存在,主要作用是用于區(qū)分請求頭部和請求主體,也就是一個CRLF
回車換行符,用于告知服務器剩下的報文中不再含有頭信息。
請求主體
也被稱為HTTP
實體,在請求報文中被稱為請求主體,這里主要描述用戶的請求數據,可以是二進制數據,也可以是請求參數等等。
1.3.2、應答報文
? ?服務器響應用戶請求時,返回的報文被稱為應答報文,大體結構如下:
應答報文主要由狀態(tài)行、響應頭、空行、響應主體四部分組成。
狀態(tài)行
應答報文中的狀態(tài)行主要由協(xié)議版本、狀態(tài)碼、狀態(tài)描述三部分構成,如下:
HTTP/1.1 200 OK
響應狀態(tài)碼也被稱為HTTP
狀態(tài),同樣存在多種,因此放在后續(xù)分析。
響應頭
和請求頭類似,遵循相同的字段規(guī)范,唯一不同點在于字段類型不同。
空行
作用與請求報文中的空行類似,主要用于分割響應頭和響應主體,用于通知客戶端剩下的報文中沒有響應頭信息。
響應主體
根據用戶請求中的資源路徑,返回對應的資源數據,可以是HTML、XML、JSON、String、Bytes
等各種數據類型。
1.3.3、HTTP報文字段
? ?在前面分析報文頭部時,提到頭部存在很多可選字段,而HTTP
報文字段主要可分為五大類:
- 請求報文字段:支持
HTTP
請求的報文字段,用于請求頭中。 - 應答報文字段:支持
HTTP
響應的報文字段,用于響應頭中。 - 實體首部字段:描述
HTTP
實體內容的報文字段,可應用在請求主體與響應主體中。 - 通用報文字段:同時支持
HTTP
請求與響應的字段,即可用于請求頭,也可用于響應頭。 - 其他報文字段:并非在
HTTP
協(xié)議中定義的報文字段,但實際過程中經常使用的字段。
請求報文字段
客戶端請求目標服務器時,可在請求報文頭部中添加的字段:
-
Accept
:代表客戶端支持的數據類型,可選項如下:- 文本類型:
-
text/html
:希望服務器返回HTML
類型的數據。 -
text/plain
:希望服務器返回普通文本類型的數據。 -
text/css
:希望服務器返回CSS
類型的數據。 -
application/xml
:希望服務器返回XML
類型的數據。 -
application/json
:希望服務器返回JSON
類型的數據。
-
- 圖片類型:
-
iamge/jpeg
:表示希望返回.jpg
格式的圖片。 -
image/gif
:表示希望返回.gif
格式的圖片。 -
image/png
:表示希望返回.png
格式的圖片。 -
image/webp
:表示希望返回.webp
格式的圖片。
-
- 視頻類型:
-
video/mpeg
:希望服務器返回視頻數據。 -
video/quicktime
:希望服務器返回MAC
電腦的視頻類型數據。
-
- 字節(jié)類型:
-
application/octet-stream
:希望返回字節(jié)流數據。 -
application/zip
:希望返回ZIP
壓縮字節(jié)數據。
-
-
*/*
:表示接受所有類型的數據返回。 -
Accept
字段可設置多個值,服務器會依次進行匹配,會返回最先匹配到的數據類型。 - 也可以通過參數
q
來設置權重,權重越高,優(yōu)先級越高,取值范圍0.000~1
,默認為1
。 - 例如
text/html,application/xml;q=0.9,*/*
,優(yōu)先匹配HTML
數據,當服務器先匹配到XML
數據時,因HTML
權重高一些,因此會依然繼續(xù)匹配HTML
數據。
- 文本類型:
-
Accept-Charset
:表示客戶端支持的字符集,如GB2312,ISO-8859-1,UTF-8
等。 -
Accept-Encoding
:表示客戶端支持的內容編碼格式,常用格式如下:-
gzip
:由gzip
壓縮算法生成的壓縮數據編碼格式。 -
compress
:由compress
壓縮算法生成的壓縮數據編碼格式。 -
deflate
:由zlib+deflate
壓縮算法生成的壓縮數據編碼格式。 -
identity
:默認的編碼格式,表示不壓縮數據。
-
-
Accept-Language
:表示客戶端支持的語言語種,如zh-cn,en,zh
等。 -
Authorization
:表示客戶端的認證信息。 -
Host
:表示客戶端訪問的目標資源所在的主機,即域名,如www.baidu.com
。 -
Referer
:資源引用鏈,也稱為防盜鏈,表示獲取資源的請求來自哪個頁面。 -
If-Match
:實體標記,該值與請求的目標資源ETag
值一致時,服務器才受理該請求。 -
If-Modified-Since
:效驗客戶端本地資源的時效性,如果本地的緩存資源沒有超時則不處理請求。 -
If-None-Match
:和If-Match
作用相反,該值與ETag
值不一致時才處理請求。 -
If-Range
:If-Match
的升級版,訪問的資源ETag
值或時間一致時,服務器處理此請求。 -
If-Unmodified-Since
:If-None-Match
的升級版,與If-Range
作用相反。 -
Max-Forwards
:最大傳輸逐跳數,也就是請求允許被轉發(fā)的最大次數,轉發(fā)一次就-1
。 -
Proxy-Authorization
:客戶端提供給代理服務器的認證信息。 -
Range
:表示獲取部分資源,如Range:bytes=50-800
,代表獲取第50~800
字節(jié)之間的數據。 -
User-Agent
:客戶端程序的信息,一般情況為當前瀏覽器的簡略信息。 -
TE
:傳輸編碼的優(yōu)先級。 ..........
應答報文字段
客戶端請求服務器后,服務器響應客戶端時,應答報文中可出現(xiàn)的字段:
-
Accept-Ranges
:表示服務器是否接受按字節(jié)范圍獲取數據的請求。 -
Age
:表示服務器創(chuàng)建響應資源的時間。 -
ETag
:實體的標識,資源的匹配信息。 -
Location
:告訴客戶端資源的重定向位置/(URL
)路徑。 -
Proxy-Authenticate
:將代理服務器需要的認證信息返回給客戶端。 -
Retry-After
:請求失敗后,告訴客戶端多久后重試。 -
Server
:告知客戶端目前服務端的HTTP
服務器信息,一般為Nginx
。 -
WWW-Authenticate
:客戶端請求資源失敗時,告知其目標資源所需的認證方案,如Basic、Digest
,一般配合401
使用。 -
status
:客戶端請求后的響應狀態(tài)。 -
Vary
:代理服務器的緩存管理信息。
實體首部字段
實體也就是指請求的目標資源,任何一個數據在HTTP
協(xié)議中都可被稱為HTTP
實體:
-
Allow
:告知客戶端所請求的資源支持的HTTP
方法,如請求方法錯誤會以405
狀態(tài)返回。 -
Content-Encoding
:告知客戶端資源(實體)數據所采用的編碼方式。 -
Content-Language
:告知客戶端資源所采用的自然語言,即zh-ch、en-US
等。 -
Content-Length
:告知客戶端資源的大小(字節(jié)長度)。 -
Content-MD5
:告知客戶端資源的報文摘要。 -
Content-Location
:告知客戶端資源所在的位置。 -
Content-Range
:告知客戶端資源接受按字節(jié)區(qū)域獲取的范圍。 -
Content-Type
:告知客戶端資源的數據類型。 -
Expires
:告知客戶端資源的過期時間。 -
Last-Modified
:告知客戶端資源最后一次的修改時間。
通用報文字段
通用報文字段是指可用于請求報文、應答報文、實體首部等多處位置的共享字段:
-
Cache-Control
:控制瀏覽器緩存的行為,常用選項如下:-
max-age=N
:請求到資源后將其緩存在本地,有效期為N
秒。 -
no-cache
:協(xié)商式緩存,請求到資源后緩存到本地,后續(xù)每次請求資源時先與服務器確認是否更新過,更新則重新請求,否則從緩存中讀取資源。 -
no-store
:禁用瀏覽器本地緩存,每次從服務器上獲取資源。 -
max-age=N,must-revalidate
:請求到資源后將其緩存,有效期為N
秒,到期后再與服務器協(xié)商確認資源是否更新,未更新則延長有效期,否則重新獲取。
-
-
Connection
:是否開啟長連接,設為Keep-Alive
代表開啟長連接。 -
Date
:HTTP
報文的創(chuàng)建時間,使用格林威治標準格式。 -
Pragma
:1.1
版本之前的歷史遺留字段,為了兼容而設計的。 -
Transfer-Encoding
:指定了報文主體傳輸時的編碼格式,如Transfer-Encoding: chunked
。 -
Upgrade
:用于檢測協(xié)議版本,是否有其他更高的版本可用。 -
Via
:追蹤客戶端和服務端之間的報文的傳輸路徑,一般在使用代理服務器時必須要用的字段。 -
Warning
:告知客戶端一些與緩存相關的警告信息。
其他報文字段
其他報文字段是指并非在HTTP
協(xié)議中定義的字段,但依舊使用頻率較為頻繁的字段:
-
Cookie
:由于HTTP
是一種無狀態(tài)協(xié)議,因此通常使用Cookie
也實現(xiàn)一些需要保持狀態(tài)的功能,如身份Token
、登錄信息等,一般用于請求報文中。 -
Set-Cookie
:一般用于應答報文中,實現(xiàn)服務器給客戶端傳遞Cookie
信息,常用屬性如下:-
Key=Value
:往客戶端的Cookie
中寫入值。 -
expires=N
:設置客戶端Cookie
的有效期。 -
domin
:指定Cookie
生效的域名,只有請求該域名時才會攜帶Cookie
。 -
path
:指定Cookie
生效的具體資源路徑,只有訪問該路徑時才會攜帶。 -
Secure
:設置該屬性后,只有安全連接(HTTPS
)情況下才會保存Cookie
。 -
SameSite
:在跨域時是否攜帶Cookie
:-
Strict
:跨域時嚴禁攜帶本站Cookie
。 -
Lax
:默認值,通過GET
方式訪問之后可允許攜帶。 -
None
:在設置了Secure
屬性情況下,所有請求都允許攜帶。
-
-
HttpOnly
:使Cookie
不能被JS
腳本訪問。
-
-
Content-Disposition
:主要用于文件上傳與下載時指定操作和名稱:- 上傳時:
-
form-data
:以表單形式提交multipart
數據。
-
- 下載時:
-
inline
:將文件內容直接在網頁上顯示。 -
attachment
:下載文件時彈出對話框讓用戶確認下載。
-
-
filename
:下載/上傳時指定文件的名稱。
- 上傳時:
OK~,大致清楚
HTTP
重的報文字段后,接著再來看看HTTP
狀態(tài)碼。
1.3.4、HTTP狀態(tài)碼
? ?在咱們做程序開發(fā)時,通過URL
訪問某個網站,通常都會在開發(fā)者調試工具重看到各式各樣的“數字”,例如常見的200、403、404、500
等,這些數字在HTTP
協(xié)議中專業(yè)稱呼為:HTTP狀態(tài)碼。RFC
中規(guī)定了狀態(tài)碼必須要為三位數,其中第一個數代表了響應狀態(tài)的類別,HTTP
中所有的狀態(tài)碼共被分為五大類別:
-
1xx/(Informational)
:信息性狀態(tài)碼,代表請求被成功接受,正在處理請求。 -
2xx/(Success)
:成功狀態(tài)碼,客戶端的請求被成功處理并返回。 -
3xx/(Redirection)
:重定向狀態(tài)碼,請求的資源位置發(fā)生變動,需重新請求。 -
4xx/(ClientError)
:客戶端錯誤狀態(tài)碼,客戶端請求出現(xiàn)錯誤導致請求失敗。 -
5xx/(ServerError)
:服務端錯誤狀態(tài)碼,請求的服務端內部錯誤導致請求無法處理。
牢記如上規(guī)則后,之后再看見狀態(tài)碼時,不管見沒見過,都可以根據其首位數字推斷出一個請求的大體狀態(tài),例如:
-
200
:以2
開頭,代表請求成功,服務端正常接受并處理了該請求。 -
301
:以3
開頭,代表請求的資源位置發(fā)生變動,請求會被重定向,重新請求新位置。 -
404
:以4
開頭,代表客戶端出現(xiàn)錯誤,請求的路徑不正確導致服務端無法定位資源。 -
500
:以5
開頭,代表服務端出現(xiàn)錯誤,服務端在處理請求的目標資源時,執(zhí)行過程出現(xiàn)錯誤。 .......
1.4、HTTP請求方法分類
? ?同時,HTTP
協(xié)議中發(fā)送請求的方法存在多種,HTTP/1.0
中提供了三個請求方法,HTTP/1.1
中新增六個請求方法:
-
GET
:一般用于獲取資源數據,如獲取用戶信息、商品信息、首頁數據等。 -
POST
:一般用于傳輸/提交資源數據,如提交表單數據、提交字節(jié)數據等。 -
HEAD
:向服務器發(fā)送類似于GET
方式的請求,但只要求返回頭信息,不返回主體數據。 -
PUT
:一般用于修改數據,向指定路徑上的資源提交最新數據并將其全量替換。 -
PATCH
:和PUT
方法類似,PUT
是全量更新,PATCH
可以只修改部分數據。 -
DELETE
:一般用于刪除資源/數據,如移除服務器上某文件資源等。 -
OPTIONS
:列出請求的目標資源所支持的請求方法,用來跨域請求。 -
TRACE
:追蹤客戶端請求/服務端響應路徑,用于測試或診斷出錯。 -
CONNECT
:在與代理服務器通信時建立連接隧道,使用隧道進行TCP
通信。
其中最常用的是GET/POST
兩種方式,其他的方法相對比而言,正常業(yè)務用的頻率并不高。
面試題:HTTP中Get和Post方法的區(qū)別
- ①
HTTP
中功能的定義不同,GET
用來獲取數據,POST
用于提交數據。 - ②傳輸數據的方式不同,
GET
直接在URL
拼接參數顯式傳輸,POST
則是隱式傳輸。 - ③允許傳輸數據時的長度不同,
GET
通常情況下受到瀏覽器和服務器的限制,因此可傳輸的參數有限,而POST
則沒有限制。 - ④
GET
總體而言,執(zhí)行的效率遠高于POST
方式,GET
也是form
表單的默認方法。 - ⑤支持的數據傳輸格式不同,
GET
僅支持ASCII
字符,而POST
支持整個ISO10646
字符集。 - ⑥安全性不同,
GET
由于是顯式傳輸,數據被放在URL
中,因此安全性遠低于POST
方式。 - ⑦瀏覽器緩存方面支持性不同,
GET
請求的資源默認會被瀏覽器緩存,下次請求相同資源會直接從本地中讀取,而POST
請求的資源默認情況下不會緩存。 - ⑧一次請求產生的數據包數量不同,
GET
只會發(fā)出一個TCP
包,POST
會將頭信息和主體信息分成兩個包發(fā)送。 - ⑨當瀏覽器回退或前進時,
GET
方式獲取的資源可直接使用,而POST
則會重新請求服務器獲取資源(因為GET
可以從本地緩存中讀取資源)。
1.5、HTTP中的其他常用核心知識
? ?在HTTP
協(xié)議中,還存在一些其他常用技術,如長連接、隧道技術、代理技術、緩存技術等,接下來再來看看這些核心內容。
1.5.1、持久連接/長連接
? ?前面曾談到過:HTTP
是基于“請求/響應”模型所構建的協(xié)議,每次請求時,客戶端和服務端之間都要新建立一個連接,服務端響應完成后又會立馬斷開連接。這種方式帶來的缺點很明顯,頻繁的創(chuàng)建/銷毀TCP
連接造成的開銷較大,資源浪費較多。
在HTTP
中為了解決頻繁創(chuàng)建/銷毀TCP
連接造成的開銷,從而設計了一種Keep-Alive
(長連接/持久連接)模式,開啟這種模式的情況下,可以復用已建立的TCP
連接,普通模式與長連接模式對比如下:
長連接模式下,當一個客戶端的請求與服務端建立連接后,這個連接并不會在服務端響應結果后立馬關閉,而是會持續(xù)有效,后續(xù)新的請求獲取服務器資源時,可以通過這個TCP
連接發(fā)送多個請求與接收多個響應。
HTTP/1.0
中默認關閉,需要手動在請求頭中添加Connection: Keep-Alive
才可開啟,HTTP/1.1
默認開啟,可以手動添加Connection: close
關閉。
對于長連接模式,聽起來確實很美好的樣子,這點無可厚非,但這種模式對于服務器而言,會造成很大的并發(fā)壓力,同時還存在一個經典問題:隊頭阻塞。
1.5.2、HTTP隊頭阻塞
? ?因為HTTP
協(xié)議事務處理機制中,要求對于請求的處理必須為“一求一應/一發(fā)一收”,所以HTTP
本質上會將請求串行化,所有的請求會被放入到一個隊列中依次交由服務器處理,那么假設前面的請求任務執(zhí)行時間過長,最終就會導致后面的所有請求全部被阻塞,因此這個問題就被稱為隊頭阻塞。
解決隊頭阻塞問題的方案有兩種:并發(fā)連接與域名分片。
- 并發(fā)連接:
一個連接中的請求會被串行化后依次遞交給服務器處理,那么假設我們客戶端同時建立多個連接,是不是就會有多個串行化的通道呢?也就是多個隊列,這答案是必然的,因此在客戶端建立多個連接,可以增加隊列數量,一個隊列中的請求阻塞,并不會影響其他隊列中的請求。
不過在
RFC2616
中規(guī)定了一個客戶端的并發(fā)連接不允許超過2
個,但實際的瀏覽器設計中并不遵循該標準,如Chrome
內核中默認允許一個域名下的并發(fā)連接值是6
個,Firefox
則是8
個。
但就算是增加到了
6
個,萬一其中4
個連接中,都出現(xiàn)了執(zhí)行時間過長的請求導致阻塞怎么辦呢?哪此時可以多上幾個域名,既采用域名分片方案。
- 域名分片:
前面提及過,一個域名可以支持多個并發(fā)連接,但如果開到了客戶端的上限后,依舊無法滿足需求會出現(xiàn)一定程度上的請求阻塞,此時我們可以多上幾個域名,也就是可以多準備幾個域名,然后域名配置的
IP
映射都指向同一臺服務器,這樣就可以支持更多的連接了,例如www.baidu.com
:
經過這個分析之后,你應該也大致清楚了為什么你做的網站訪問速度慢的主要原因之一,因為你的請求出現(xiàn)了隊頭阻塞,服務器串行處理的速度過長,導致了你網頁加載速度過慢。
1.5.3、HTTP代理技術
? ?一般情況下,客戶端和服務端之間的通信都是采用直連模式,即客戶端解析域名后直接根據IP
請求后端服務器,然后服務器處理客戶端請求。但這種模式下,假設后端節(jié)點出現(xiàn)故障宕機,那么整個系統(tǒng)則會陷入癱瘓。同時這種模式,也無法解決部署后端節(jié)點的服務器性能瓶頸問題,因此為了確保系統(tǒng)更高的可用性和穩(wěn)定拓展性,此時則可以加入 HTTP
代理。HTTP
代理大家聽的次數應該也不算少,代理的主要含義是指:在客戶端與服務端之間假設一個節(jié)點,從而能夠滿足開發(fā)過程中的更多需求,如動靜分離、負載均衡、服務高可用、網站安全等,大體示意圖如下:
代理服務器目前市面上也存在多種選擇,如Varnish、Squid、Nginx
等,這些代理服務器的工作模式又可被分為正向代理和反向代理。
正向代理
? ?正向代理與反向代理,這也是面試過程中常遇的一個面試題,先來談談何謂正向代理。
正向代理是指客戶端可以感知到“代理角色”的存在,客戶端發(fā)送請求時需要指定目標服務端,然后代理服務器會將客戶端的請求發(fā)送到目標服務器處理,服務端處理完成后,代理服務器會接收響應結果并將其返回給客戶端。
這樣理解起來可能會存在些許抽象,那么例舉生活中的例子:“竹子喊熊貓去樓下小賣部買包煙”,這個例子中“竹子”是客戶端,“熊貓”是代理服務器,“小賣部”是服務端。
“竹子”顯然知道有“代理人”的存在,并且明確指定了目標,但“小賣部”卻無法知道具體要買煙的人是誰,這就可以理解為“正向代理”。
反向代理
? ?反向代理的含義是指:代理服務器的存在對于客戶端而言,是無法感知的。簡單來說,就是指用戶在訪問代理服務器就跟直接訪問服務器一樣。
當用客戶端根據域名解析IP
訪問時,其實解析得到的是反向代理服務器所在的機器IP
,當客戶端請求發(fā)送到反向代理服務器時,代理服務器會將請求分發(fā)到具體的“服務端機器”上處理,服務端處理完成后會將數據返回給反向代理服務器,然后由代理服務器將結果響應給客戶端。
在這種“反向代理”的過程中,客戶端對于“代理服務器”是無感知的,并且具體處理請求的服務器對于用戶而言也是“黑箱”的。當然,為了便于理解,咱們再舉個例子講解:
竹子創(chuàng)業(yè)做xx
業(yè)務,需要一批貨,竹子找到當地供應商熊貓,熊貓收到竹子的拿貨需求后,轉手交給了X
工廠,工廠完成貨物生產后,交給“供應商熊貓”,再由熊貓交給“創(chuàng)業(yè)者竹子”。
? ?上述案例里,竹子依舊是“客戶端”,而熊貓依舊是“代理人”,工廠則是“服務端”,但這個過程中,“創(chuàng)業(yè)者竹子”是無法感知出“供應商熊貓”是代理人的角色,同時負責真正貨物提供的“服務商工廠”對于竹子而言也是不可見的,這個案例就是一個典型的“反向代理”。
代理服務器這方面的內容會在下一篇中詳細闡述。
1.5.4、HTTP隧道代理
? ?前面分析的正向代理也好,反向代理也罷,其實都屬于普通代理,在此之外還存在一種叫做隧道代理 的概念。
為什么需要隧道代理的存在呢?因為之前的普通代理模式中,代理服務器是“中間人”的角色,此時假設需要傳輸HTTPS
流量,因為HTTPS
需要認證,但代理顯然不可能有網站的私鑰證書,最終就會導致客戶端和代理之間的TLS
無法建立,證書校驗無法通過。文章來源:http://www.zghlxwxcb.cn/news/detail-845006.html
HTTP tunnel
以及CONNECT
機制就主要解決了這個問題,代理服務器不再作為中間人,不再改寫瀏覽器的請求,通過CONNECT
方法讓客戶端與任意目標服務器的IP
和端口建立一條TCP
連接,創(chuàng)建成功后,隧道代理在其中只負責將瀏覽器和服務器之間通信的數據原樣透傳,這樣客戶端就可以直接和遠端服務器進行TLS
握手并傳輸加密的數據。文章來源地址http://www.zghlxwxcb.cn/news/detail-845006.html
1.6、HTTP各版本中的缺陷與改進
-
HTTP/0.9
:僅支持GET
方式的純文本請求。 -
HTTP/1.0
:- 特點:無狀態(tài)、無連接,支持多類請求方式,任意數據都可以傳輸。
- 缺點:每次請求時無法復用連接,需重新建立連接。
-
HTTP/1.1
:- 改進:
- 支持長連接(
Connection: keep-alive
)。 - 支持管道化請求。
- 支持緩存管理,分為強緩存和協(xié)商緩存兩種。
- 支持斷點續(xù)傳。
- 支持一個
WEB
服務器創(chuàng)建多個站點(Host
)。 - 增加多個請求方法。
- 支持長連接(
- 不足:
- 傳輸性能有限,請求會發(fā)生阻塞(隊頭阻塞)。
- 改進:
-
HTTP/2.0
:- 改進:
- 引入新的二進制協(xié)議,應用層與傳輸層之間數據支持二進制分幀。
- 引入多路復用機制,提高連接可用性。
- 優(yōu)化請求頭,使用
HPACK
頭部壓縮算法避免傳輸重復頭。 - 支持服務器主動向客戶端推送資源。
- 不足:
- 因基于
TCP
協(xié)議構建,出現(xiàn)丟包時,整個會話需等待重傳,后面數據會被阻塞。
- 因基于
- 改進:
-
HTTP/3.0
:- 改進:
- 拋棄
TCP
協(xié)議,轉至基于UDP
協(xié)議構建的QUIC
協(xié)議(又稱HTTP/3.0
)。 - 新增
0-RTT
機制:緩存當前回話上下文,下次恢復會話將緩存?zhèn)鹘o服務器驗證后,即可傳輸數據。 - 優(yōu)化多路復用機制:會話的多個流間不存在依賴,丟包只需重發(fā)包,無需重傳整個連接。
- 針對移動端應用優(yōu)化:由于之前基于
TCP
協(xié)議,因此對于移動端的IP
多變而言,非常影響傳輸,3.0
通過ID
識別連接,ID
不變,即可快速連接。 - 更好的安全性:
3.0
中幾乎所有報文都要經過認證,主體經過加密,有效防竊聽、注入和篡改。 - 提供向前糾錯機制:每個數據包中攜帶部分其他數據包的數據,少量丟包可通過其他包的冗余數據直接恢復,無需丟包重傳。
- 拋棄
- 改進:
到了這里,關于【Java網絡編程】HTTP超文本傳輸協(xié)議的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!