網絡原理 HTTP/HTTPS
HTTP,全稱為"超文本傳輸協議"
HTTP 誕?與1991年. ?前已經發展為最主流使?的?種應?層協議.
實際上,HTTP最新已經發展到 3.0
但是當前行業中主要使用的HTTP版本還是 1.1
應用場景
(1)網頁與服務器之間的交互
(2)手機APP 與 服務器 之間的交互
雖然HTTP作用很大,應用很廣,但是在實際開發里面,不一定真正直接使用HTTP,更大的概率是使用HTTPS
HTTPS,本質上還是HTTP,但是引入了額外的加密層(此處的s => 安全)
抓包工具
進一步理解HTTP協議的工作流程,以及理解 HTTP協議的報文格式,需要用到 “抓包工具”
所謂抓包,即使能夠把網絡上傳輸的HTTP數據獲取到,并且顯示出來
而抓包工具就是一個代理程序
我們常使用的HTTP抓包工具就是 Fiddler
我們使用fiddler 并且用瀏覽器打開 搜狗的網頁:
這些都是給搜狗服務器發送的請求數據
(瀏覽器訪問一個網站的時候,往往不是只發送一個請求,很可能是發送很多個請求)
我們關注的是藍色的 ,并且body這一列數據比較多的請求
(藍色的是服務器返回的HTML數據,黑色的就是返回的普通的數據,同時還會存在其他不同的顏色區分 => css js 圖片等)
此時用fiddler抓取請求的時,右邊就會有兩部分
這個就是請求的詳情(右上角)
這個是響應的詳情
實際上HTTP本來是 文本協議,但是如果需要返回的響應比較大,就可能需要將響應數據壓縮再返回
服務器里面就寶貴的硬件資源就是 網絡帶寬
經過壓縮就是用cpu資源,置換貸款資源
對于瀏覽器來說,解壓縮就是 自動完成的
對于fiddler來說,就需要手動解壓縮
http請求報文
我們來理解一下請求報文里面涉及的主要內容
首行
首行又包括3部分,分別是
(a)請求的方法
就是用來表示,當前這個請求要做什么,這里是get,就是表示要從服務器獲取某個數據
(b)請求的URL
表示請求對方的網址
?版本號
表示http協議的版本
在首行里面,是使用空格來區分三部分的
請求(header)
Host: sogou.com
Connection: keep-alive
sec-ch-ua: "Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9
Cookie: SUID=B2F2E6B75019870A0000000065E83505; cuid=AAEhDK3JSgAAAAqHS15V8gEASQU=; SUV=1709716740486165; SMYUV=1712055327421647; ABTEST=3|1716650944|v17; SNUID=7E584C1EAAAFB3E158142029AA686AC3
header里面可以包含若干行數據
此處本質上是一個 "鍵值對"結構
每一行就是一個鍵值對,鍵和值之間是通過 : 分割的
這里的鍵,都是標準已經規定好了的
空行
最后一個header后面,存在一個空格,就是用來標識 header什么時候結束
正文body
可選的,有些情況下有正文,有些情況下則沒有
這里的內容是任意的,可以是 完整的HTML,也可以是完整的css / js,或者json數據 / 文件 / 字體…
響應報文
http響應這里也是有4部分的
首行
首行也分成3部分
(a)HTTP版本
(b)狀態碼
?狀態碼描述
狀態碼和 狀態碼描述,就是用來表示當前這個請求,是一個成功的現響應還是一個失敗的響應
如果失敗,具體是什么原因
響應的報頭header
Content-Security-Policy: script-src 'report-sample' 'nonce-DZQj_AIZgPzZ8U3IlRD6Rg' 'unsafe-inline' 'strict-dynamic' https: http:;object-src 'none';base-uri 'self';report-uri https://csp.withgoogle.com/csp/clientupdate-aus/1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Date: Sat, 25 May 2024 16:07:58 GMT
X-Cup-Server-Proof: 3045022053fcd15abefbd905af6aec3d7b1d8e22d568cfaef94045db64c55c6d360911760221009c9723e72e9aac45564bbe973b9a2d5d770605694f39c1d49c849f53c7a6609b:04476c6afa69f5b08dd45f8ea917d5749db193b1f2b53cd712a033d88b4545a0
ETag: W/"3045022053fcd15abefbd905af6aec3d7b1d8e22d568cfaef94045db64c55c6d360911760221009c9723e72e9aac45564bbe973b9a2d5d770605694f39c1d49c849f53c7a6609b:04476c6afa69f5b08dd45f8ea917d5749db193b1f2b53cd712a033d88b4545a0"
Content-Type: application/json; charset=utf-8
X-Daynum: 6354
X-Daystart: 32878
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Content-Length: 461
這里和請求的報頭一樣,鍵都是標準規定好的
空行
響應頭的結束標記
正文
這些就是我請求搜狗的網頁時,返回的響應正文
http請求
認識URL
平時我們俗稱的 “?址” 其實就是說的 URL (Uniform Resource Locator 統?資源定位符).
協議方案名
協議?案名. 常見的有 http 和 https, 也有其他的類型. (例如訪問 mysql 時?的jdbc:mysql)
登錄信息
這是很久之前的方式,就是描述了你登錄的時候的信息,現在基本不這么干了,都是搞一個登錄頁面
服務器地址
描述了要訪問的服務器的IP / 域名
服務器端口號
如果這里我們自己不寫的話,瀏覽器就會自己這個URL設置一個默認的端口,這個端口號指的就是訪問的服務器的端口號
如果是http協議端口號使用80,如果是https協議,端口號就是443
如果服務器的端口號不是默認的80 / 443,那么我們就必須在url里面顯示寫出來端口號
但是實際上一般來說,一個網站都會使用默認的端口,大部分網站還是通過80/ 443來進行部署的
帶層級的文件路徑
指定了要訪問服務器的哪些資源
一個服務器,可以提供很多的資源供外界訪問
比如,web服務器(網站),就可能包含很多的不同的資源,就可以通過這里的路徑區分不同的網頁資源了
此時通過Ip 確定主機
結合端口號 確定主機上的程序
結合路徑確定程序里的哪個資源
結合這三部分,就能夠確定互聯網上的唯一網址了
查詢字符串
就是瀏覽器傳輸給服務器的時候,攜帶的一些參數
通過參數,將客戶端想傳給服務器的信息告知過去
查詢字符串也是鍵值對的格式
使用& 來進行多對鍵值對之間的分割
使用 = 來進行鍵和值之間的分割
片段標識符
是用來區分頁面中不同部分的目錄 / 導航
比如我們訪問https://v2.cn.vuejs.org/v2/guide/#%E8%B5%B7%E6%AD%A5這個網站的時候,點擊不同的導航,實際上還是在同一個頁面,但是是不同的內容
關于url encode
?實際上,在url里面存在很多的特殊含義的符號,比如: / ? = & 等等
而在query string里面的value部分,一旦也包含這些符號,那不就亂套了嗎,就會使得url的解析出現問題
而encode就是針對value進行轉移
而也會觸發不僅僅是符號,中文漢字也會觸發轉義
為什么不直接使用漢字?? 實際上,漢字是utf8 / gbk編碼
如果某個漢字的恰好某個字節,就和某個特殊符號的ascii碼值重復了,此時就可能會導致解析的時候出現問題
那么具體是怎么轉碼的呢??
實際上就是,遇到需要轉碼的字符,就顯示出這個字符原始的編碼的十六進制,在這個基礎上,加上%
就比如上面的c++,+的ascii碼值的十六進制就是2B,那么轉移后就是 %2B
如果是漢字,就把utf8編碼結果,每個字節前面,加上 % ,按照16進制的方式來表示
在解析URL的時候,見到帶 % 就知道特殊的轉碼后的是數據了,就可以很容易的和特殊符號區分開來
認識方法
方法就是動作/意圖,在http請求首行里,就包含了方法,語義就是,這次請求我要干啥
get方法 和 post方法
get的語義是從服務器獲取某個數據
post的語義是往服務器提交某個數據
但是實際上這是最初設計出來的目的
現如今使用這兩個方法的時候已經很少區分開了
即get也可能用來提交數據,post也可能用來獲取某個數據
但是在習慣上的差別是
get請求報文里面通常不會 攜帶body,有要傳輸的傳輸,就是使用url的query string
詳細請訪問關于http方法中get和post的區別
而post通常使用的是body傳輸數據
現實網絡上大部分請求都是get
至于post就比get少很多,就是登錄 / 上傳文件
其他方法
put方法:也是用來給服務器提交數據的,和post非常類似,不一定用來提交文件
delete是用來刪除文件的,與get類似,沒有body,使用的是query string
構造不同的方法請求
對于get方法
(1)在瀏覽器地址欄直接輸入 url,此時就是get請求
(2)網頁html中會有一些特殊的標簽,img / a /link 這些標簽,會帶有一個url屬性,頁面被 瀏覽器加載之后,解析到這些標簽,就會根據url構造出新的http請求
(3)表單 通過html中特殊的標簽form
(4)通過js構造
比如用原生的 ajax api / jquery 的 ajax api / 第三方庫 axios ,fetch…
post
(1)表單
(2)js