一.一個完整的 HTTP 連線
一個完整的 http 連線有五個步驟;
1.TCP 三次握手
該部分表示 A 向 B 發出請求,建立連線
(一)第一次握手(A->B):
A 向 B 傳送一個 TCP 的包,帶上了標誌 SYN
,表示要建立一個連線,並指明包開始的序列號 seq,以後傳送的位元組編號都是以這個作為起點,並告知能接收的最大報文段長度 mms 為 1460,一般 mms 都是1460.
(二)第二次握手(B->A):
B 進行回覆,傳送一個 SYN + ACK 的報文段,表示同意建立連線
(三)第三次握手(A->B)
A 收到 SYN 之後,向 B 傳送一個 ACK,完成三次握手。
為什麼 TCP 握手要三次?
TCP 前兩次的握手就可以確定對方的存在,第三次的握手是為了防止已失效的連線請求報文段突然又傳送到B,因而產生錯誤。 異常情況:假設 A 向 B 傳送了一個連線請求報文段,但是因為某些網路結點長時間滯留,以致延遲到連線請求釋放後的某個時間才到達 B。本來這是一個早已失效的請求報文段,但 B 收到此失效請求報文段後,就誤認為 A 又發出一次新的連線請求。於是就想 A 發出確認報文段。若,只有兩次握手,B 就是一隻建立連線,浪費資源。但如果有 第三次握手,B 一直都沒有接收到 A 發回來的第三次確認,就會自動斷開連線。
2.接收視窗
(一) TCP 的流量控制
通過滑動視窗機制進行流量控制
(二) TCP 的擁塞控制
- 慢開始和擁塞避免
- 快速重傳和快恢復演算法
此處簡寫接收視窗的控制機制
3.傳送資料
此部分省略吧~
4.關閉連線 四次揮手
(一)第一次揮手
當 A 覺得不用再請求資料時,等過了 30S 就要把請求連結關閉,向 B 傳送一個 FIN 的報文。
為什麼需要等 30s 才關閉呢?
因為 HTTP 1.1 版本之後的請求的 Connection:keep-alive 欄位的影響。因為同一個域可能要請求多個資源,如果每請求一次就關閉連線。下次請求時,又要建立 TCP 連線,是浪費資源的。
(二)第二次揮手
B 收到 A 發來的包後,向 A 傳送一個 ACK ,這時連線處於半關閉狀態,A 不能向 B 傳送資料,但是 B 可以向 A 傳送資料。
(三)第三次揮手
當 B 覺得沒有資料需要傳送時,向 A 傳送 FIN
(四)第四次揮手
A 收到 B 發來的結束連線請求,向 B 傳送一個 ACK ,此時連線完全關閉。然後主動關閉方 A 進入 TIME_WAIT (時間等待)狀態。
5.TIME_WAIT
TIME_WAIT 時間為 2MSL(maximum segmentt live-time),標準建議為 2 分鐘,但是實際運用中,2 分鐘太長了。
為什麼 A 在 TIME_WAIT 狀態下必須等待 2MSL ?
原因有二,一是:為了保證 A 最後傳送的 ACK 能夠成功到達 B 端。二是:防止上一節“三次握手”處提及到的“已失效的連線請求報文段”出現在本連結中。A 在傳送完最後一個 ACK 報文段後,再經過 時間 2MSL 後,就可以使本連線持續的時間內所產生的所有報文段都從網路中消失。
http/https 協議
1.http協議格式
- request: request-line(由三部分組成 1.請求方法;2.請求地址;3.請求協議和版本) head body
- response response-line(由三部分組成 1.協議和版本,狀態碼,狀態文字) head body
2.http狀態碼和狀態文字
- 1XX 臨時迴應,表示客戶端請繼續
- 2XX
- 200 請求成功
- 3XX 表示請求的目標有變化,希望客戶端進一步處理
- 301&302 永久性和臨時性跳轉
- 304 客戶端快取沒有跟新
- 4XX
- 403 沒有許可權
- 404 頁面不存在
- 418 it‘s a teapot
- 5XX 服務端錯誤
- 500 伺服器錯誤
- 503 伺服器端暫時性錯誤,可以一會再試
3.http request Head 請求頭
- accept 瀏覽器端接受的格式
- accept-encodind 瀏覽器端接受的編碼格式
- accept-language 瀏覽器端接受的語言
- cache-control 控制快取的時效性
- connection 連線方式 如果是 keep-alive 且瀏覽器支援,會用複用連線
- host http訪問使用的域名
- if-modified-since 上次訪問時的更改時間,如果伺服器端認為此後沒有更新,則會返回304
- if-none-match 上次訪問的etag,通常是頁面的資訊摘要
- user-agent 客戶端表示
- cookie 客戶端快取的餓cookie 字串
4.http response head 響應頭
- cache-control 快取控制 用於通知各級快取儲存的時間
- connection 連線方式
- content-encoding 內容編碼 通常是 gzip
- content-length 內容長度 ,瀏覽器用於判斷內容是否已經結束
- content-type 內容型別,所有請求網頁的都是 text/html
- date 當前伺服器時間
- eatg 頁面的資訊摘要,用於判斷是否需要重新到伺服器取回頁面
- expires 過期時間,用於判斷下次請求是否要到伺服器端取回頁面
- keep-alive 保持連線不斷時需要的一些資訊,如 timeout,max
- last-modifiled 上次修改時間
- server 伺服器軟體型別
- set-cookie 設定cookie
- via 服務端的請求鏈路
5.http request body 響應體
- application/json
- application/x-www-form-ulencoded
- multipart/form-data
- text/html
6.https
https 有兩個作用:
- 一是用於確定請求的目標伺服器的身份;
- 二是保證傳輸的資料不會被網路中間竊聽或者篡改,即是防止中間人攻擊。
(一)中間人攻擊方式
1.域名汙染
由於我們訪問一個域名時需要先進行域名解析(在沒有快取的情況下),即向 DNS 服務請求某個域名的 IP 地址。在經過 DNS 的中間鏈點可能會被搶答,返回一個錯誤的 IP 地址,這個 IP 地址有可能就指向中間人的機器。
2.APR 欺騙
廣域網的傳輸用的是 IP 地址,而在區域網裡面是用實體地址,例如路由器需要知道連線它的裝置的實體地址才能傳送資料包,當路由器不知道對應的實體地址時,會通過 ARP 廣播,向所有裝置查詢某個 IP 地址對應的實體地址。由於這個區域網內的所有機器都會受到這個包,所以這時候就可以欺騙路由器。
安全
xss (cross site scripting)
是一種網站應用程式的安全漏洞,它允許惡意者將程式碼注入到網頁上。通過修改 html 結點或者執行 js 程式碼來攻擊網站
防禦:
- 轉義輸入輸出的內容,設定白名單
- CSP content-security-policy,通過在 http header 中開啟 CSP。本質上,也是設定白名單,通過規範瀏覽器只能夠執行特定來源的程式碼
只允許載入本站資源 Content-Security-Policy: default-src ‘self’
只允許載入 HTTPS 協議圖片Content-Security-Policy: img-src https://*
允許載入任何來源框架Content-Security-Policy: child-src 'none'
- cookie 設定 httpOnly
CSRF (cross site request forgery)
簡單地說,就是利用使用者的登入態發起惡意請求
防禦
- get 請求不對資料進行修改
- 不讓第三方網站訪問到 cookie
可以對 Cookie 設定 sameSite ,該屬性設定 Cookie 不隨著跨域請求傳送。
- 阻止第三方網站請求
通過驗證 referer 來判斷請求是否為第三方網站發起
- 請求時,附帶驗證資訊,如驗證碼或者 token
伺服器下發一個隨機的 token,每次請求都將 token 帶上,伺服器判斷 token 是否有效。
(未完待續 ...)
歡迎大家在評論區共同探討 ~
希望寫的文章能夠為同在坑裡的你我解答一點點的疑問~
參考文獻
- 《計算機網路》(第七版)謝希仁著
- 《高效前端》李銀城著