疫情雖然沒有結束,不過學習始終是不能停的。這次的內容主要以網路為主,也是依據正常面試中常被問及的話題進行了梳理
每個點都沒有過分的深究,也是為了文章字數不要太過龐大考慮的,點到為止,是這次的主題
那麼,讓我們閒言少敘,開始進入主題吧!!!
http
http1.1和http2.0
如果要說http1.1和http2.0的區別,那就先要說http1.1和兄弟http1.0的區別了
現在我們常用的http協議也是http1.1這個版本的
http1.1支援
- 長連結,預設是
Connection: keep-alive
- 減少了TCP建立和關閉連線的消耗和延遲,一次建立多次請求和響應
- 快取處理
- http1.0使用頭部的
Expires
和Pragma
來控制快取 - http1.1裡支援了更多的快取策略,
Etag、If-Modified-Since、If-Unmodified-Since、If-Match、If-None-Match、Cache-Control
- http1.0使用頭部的
- Host頭處理
- 同一臺機器上,可能部署多個app,通過解析host+埠,指定具體訪問站點
好了,知道了現在市面上最廣泛的協議都可以做什麼,那麼就再來看看http2.0這個時隔了16年的小朋友都有哪些過人之處吧!!!
其實與其說http2.0的過人之處,不如說它是在優化http1.1上的不足
下面寫的都是在改善以前的缺點,一起看看吧
http2.0支援
頭部壓縮
頭太大,太重,暈暈的,需要減負
-
體積壓縮
- 所以http2.0採用了HPACK演算法壓縮了header的大小
-
快取header
- 對傳輸過的header進行快取,如果有傳輸過header的鍵名,就不再重複傳送了,減少了傳輸的大小
多路複用
解決了什麼問題?
答: 瀏覽器限制同一個域名下請求的數量,(chrome好像是6個)
多路複用的大致意思就是
- 在一個TCP連線中可以同時傳送多個請求,避免線頭阻塞問題,極大的提高傳輸效能
服務端推送
就是服務端主動的把你必定需要的資源推送給你,讓你在請求一次的情況下得到多個響應資料
舉個例子,比如你訪問了首頁,伺服器就會主動的把首頁的css,js,圖片
等資源都主動推送過去,畢竟這些都是必須的資源
好了,http1.1和http2.0版本之間的不同就簡簡單單的寫到這裡吧,由於本人也不是科班出身,對這種計算機網路知識實在匱乏,就先點到為止吧,下面繼續看其他的
http和https的區別
其實談及二者的區別,也是在告訴大家http有哪些不安全因素
那麼我們來看看不安全的點都有哪些吧
之後你就會明白https的出現到底多麼有意義了
不安全的http
- 資訊被竊聽
- http的報文是使用明文方式傳送
- 認證問題
- 通訊雙方在請求和響應時無法確認
- 劫持資料
- 請求和響應的傳輸過程中,容易被運營商劫持,篡改資料,無法保護資料的完整性
https夠安全
https的埠是443,它基於http協議,通過ssl
或tls
提供加密處理資料、驗證對方身份以及資料完整性保護的
https是在http(應用層)和tcp(傳輸層)之間加了一層ssl協議,來進行加密,從而變成了我們所知的https
組成部分: https = http + ssl/tls
下面我們就簡單聊聊ssl/tls
協議
ssl和tls
ssl/tls
用來處理資訊加密、完整性校驗、身份驗證
ssl/tls
基於三類演算法實現
- 對稱加密 -> 資訊加密
- 我們擁有同一把鑰匙來開門(客戶端|服務端有相同的鑰匙),別人沒鑰匙開不開
- 非對稱加密 -> 身份驗證金鑰協商
- 我們都能進飯店吃飯(公鑰),但是收銀臺的鑰匙(私鑰)只有老闆有
- 雜湊演算法 -> 完整校驗
- 只有你自己的指紋(加密)可以解鎖門鎖
連線過程
- 首先建立tcp握手連線
- 進行ssl協議的握手金鑰交換
- 通過共同約定的金鑰開始通訊
通過以上內容的瞭解,https是網站安全的代言人,儘快的都使用上https協議吧
http報文頭部有哪些欄位?有什麼意義?
通用頭欄位
欄位名 | 常見值 | 意義 |
---|---|---|
Connection | keep-alive | 連結的管理 |
Cache-Control | max-age=xxx秒 | 控制快取行為 |
Date | 日期和時間 | 報文日期 |
Transfer-Encoding | chunked | 報文主體的傳輸編碼方式 |
請求頭欄位
欄位名 | 常見值 | 意義 |
---|---|---|
Accept | * / * | 處理的媒體型別 |
Accept-Encoding | gzip | 編碼型別 |
Accept-Langulage | zh-CN,zh | 編碼語言 |
Host | 域名或IP | 指定具體訪問站點 |
If-Modified-Since | 日期和時間 | 比較資源更新的時間 |
If-None-Match | Etag戳 | 比較實體標記 |
Referer | 域名或IP | 請求來源 |
User-Agent | 瀏覽器版本資訊 | 使用者代理 |
響應頭欄位
欄位名 | 常見值 | 意義 |
---|---|---|
Content-Encoding | gzip | 主體編碼型別 |
Content-Type | application/json或text/css等 | 主體媒體型別 |
Expires | 日期和時間 | 過期時間 |
Last-Modified | 日期和時間 | 最後修改時間 |
Etag | Etag戳 | 資源匹配資訊 |
http響應狀態碼
狀態碼想必是經常見到的東西了,這裡要是展開說的話也會有很多內容的,
不過我們依然從頭開始,梳理一下常見的狀態碼以及使用情況
狀態碼總共分為5個大類
- 1xx: 資訊類狀態碼(屬於準備階段)
- 2xx: 成功狀態碼
- 3xx: 重定向狀態碼
- 4xx: 客戶端錯誤狀態碼
- 5xx: 服務端錯誤狀態碼
各大類中常見的狀態碼
每個大類中都有我們常見的狀態碼,不多不少,我們都有過照面,這就足夠了
2xx - 成功系列
- 200 - 請求成功
- 204 - 返回響應頭,不帶響應體(如:打點請求)
- 206 - 返回部分資料(如:斷點續傳)
3xx - 重定向系列
- 301 - 永久重定向
- 302 - 臨時重定向
- 303 - 只能用get請求的臨時重定向
- 304 - 沒有更改(主要用來處理快取)
- 307 - 不改變請求方法的臨時重定向
4xx - 客戶端錯誤系列
- 400 - 請求報文語法錯誤
- 401 - 需要認證
- 403 - 拒絕訪問資源
- 404 - 檔案不存在
5xx - 伺服器錯誤系列
- 500 - 伺服器故障
- 503 - 伺服器當機了
大概就把關於http部分的內容先說到這裡吧,下面我們來說一下老生常談的話題:快取,快取的作用想必不用說也知道(減少資料傳輸,提高網頁速度),所以我們就直奔主題進入快取吧
快取
快取主要分為兩種,一種是強制快取,另一種就是協商快取了(304其實就是協商快取)
強制快取
強制快取通常是用在圖片或者logo這樣長久不會更改的資源上的
當第一次訪問資源的時候,會正常拿到200的狀態碼
當第二次訪問資源的時候,就會去瀏覽器的快取裡找快取檔案使用了,不過返回的狀態碼仍然是200
強制快取主要是通過Cache-Control
和Expires
來設定的
Cache-Control
通過在服務端設定響應頭來新增Cache-Control
如: Cache-Control: max-age=100
max-age
是一個相對時間,單位是秒
上面那行表示強制快取100秒內不再去伺服器拿資源,而是直接使用瀏覽器的快取裡的檔案
Expires
Expires可以說是很早就有了,之所以設定強快取的時候還設定它也是為了相容低版本
如: Expires: new Date(+new Date + 20 * 1000).toUTCString()
Expires接收的是絕對時間,單位是毫秒,並且要轉成格林威治時間,以前的toGMTString()
已經廢棄了,現在統一用toUTCString()
優先順序
由於Expires是一種向下相容的方式,所以如果同時有Cache-Control
和Expires
被設定的情況下,強快取會只認Cache-Control
ok,說完了強制快取,就輪到協商快取登場了,對於協商快取來說也經常是考點之一
協商快取
還是一樣的套路
當第一次訪問資源的時候,會正常拿到200的狀態碼,服務端會把快取標識和資料一起返回
當第二次訪問資源的時候,就會把快取標識發給服務端,服務端去校驗是否匹配,匹配成功就返回304,直接使用快取即可
協商快取常見的也是兩種,一種是Last-Modified,另一種是Etag
先從Last-Modified說起吧
Last-Modifed
Last-Modified
從單詞的大意可以看出,表示的是最後修改時間
客戶端訪問資源,服務端會設定一個響應頭為Last-Modified
並且把值設定為絕對時間
這樣客戶端再訪問同一個資源的時候,請求頭上會帶有一個If-Modified-Since
的欄位
關鍵點:
服務端會通過客戶端發來的If-Modified-Since
和Last-Modified
的值比較
- 相同: 返回304狀態碼,使用快取檔案
- 不相同: 返回200狀態碼,請求資源
缺點:
- 時間不精確,如果最後修改時間變了,可是內容沒有變就失效了
- 舉個例子:
- 比如我5秒前改了個值,重新整理請求返回200
- 然後我又撤銷了剛才改的程式碼,再重新整理請求又返回200
- 但是其實我的內容沒有改變,只是根據我修改的時間來判斷,就不太準了
解決這個問題並不難,直接把下一位主角請上來
Etag
ETag
是實體標籤的縮寫,根據實體內容生成的一個hash戳
,只有內容改變了Etag
才變
流程一樣,還是客戶端第一次訪問資源時,服務端會把Etag
和資料一起返回
再次訪問資源時,請求頭就會有個If-None-Match
欄位並且也會傳送給服務端
一樣的關鍵點:
服務端會通過客戶端發來的If-None-Match
和Etag
的值比較
- 相同: 返回304狀態碼,使用快取檔案
- 不相同: 返回200狀態碼,請求資源
強制不快取
曾經有道題目問的是不快取有哪些方式?
其實很簡單,只要在設定Cache-Control: no-store
就可以了
但是很多人也都見過no-cache
這個值,實際上它依然會快取但是每次都像伺服器發請求罷了
跨域
跨域是前端同學見怪不怪的問題了,瀏覽器本著安全的原則採用了同源策略
要求只有域名、協議、埠號`都相同的才可以進行請求
概念的東西,我就不囉嗦了,下面直接開始說跨域的幾種方式吧
- jsonp
- 通過script的src來進行跨域請求,把資料包在一個函式內傳遞過來
優點:使用簡單、相容性好
缺點:只支援get請求,不夠安全有XSS攻擊的危險
複製程式碼
- cors
-
傳送請求時會附帶一個Origin頭部包含請求頁面的源資訊(協議、域名、埠號)
-
服務端根據頭資訊來進行處理,如果接受就在
Access-Control-Allow-Origin
頭部回發相同的源資訊實現跨域
-
優點:使用方便
缺點:瀏覽器相容問題,修改主要在後端
複製程式碼
- postMessage
- 兩個頁面(視窗)之間的通訊,可以和內嵌的iframe通訊
iframe.contentWindow.postMessage(資料, 目標域名)
優點:H5提供的API,使用方便
缺點:瀏覽器相容問題,而且需要依賴iframe
複製程式碼
- window.name
- name屬性在不同的頁面也存在
簡單用法:
在localhost:8000/2.html
頁面中新增資料到window.name,看下面程式碼
// 這是http://localhost:8000/2.html頁面
<script>
let list = [1,2,3,4,5];
// 由於window.name內部呼叫了toString方法
// 所以如果你想要得到你想要的資料型別,就需要先進行JSON.stringify
window.name = JSON.stringify(list);
</script>
複製程式碼
現在localhost:9000/1.html
想拿到上面的資料,就需要藉助window.name來取了
// 這是http://localhost:9000/1.html頁面
<body>
<div>我是1頁面,裡面有巢狀頁面</div>
<iframe src="http://localhost:8000/2.html" id="f" onload="load()"></iframe>
<script>
let flag = true;
function load() {
if (flag) {
// 頁面第一次載入完成就把iframe的src修改為同域下的3.html頁面
f.src = 'http://localhost:9000/3.html';
flag = false;
} else {
// 之後再載入新的src的時候就可以拿到window.name上掛載的資料了
const data = JSON.parse(f.contentWindow.name);
console.log(data); // [1,2,3,4,5]
}
}
</script>
</body>
複製程式碼
優點:掛到window.name上寫法很簡單
缺點:依賴iframe,且掛載到window.name上不安全
複製程式碼
- domain
- 二級頁面通過
document.domain
設定相同的域名,強制實現了同域
- 二級頁面通過
優點:設定方便
缺點:依賴iframe,只支援一級和二級域名
複製程式碼
- webSocket
- 雙工通訊,沒有跨域限制,需要前後端建立websocket連線,開始通訊
優點:H5的API,用法簡單
缺點:相容問題,需要後端提供ws服務
複製程式碼
網路安全
XSS
使用者輸入的內容可能會有惡意程式碼
所以,一句話就是轉義使用者輸入的內容,轉義轉義轉義(encodeURICompoent)
// 轉義html裡的字元
function encodeHtml(str) {
return str.replace(/&/g, '&').
replace(/"/g, '"').
replace(/'/g, '&apos').
replace(/</g, '<').
replace(/>/g, '>')
}
複製程式碼
CSRF
跨站請求偽造,如:釣魚網站
- 驗證碼校驗
- express可以用個svg-captcha生成驗證碼,後臺進行校驗
- 判斷來源 referer
- 請求頭裡的referer判斷來源,不一致的不處理
- token
- 釣魚網站不能拿到cookie,可以通過cookie+識別符號發給服務端,讓服務端去匹配傳送的token是否一致
- 在登入後服務端會返回token,前後端拿著token進行匹配,一樣的就可以
TCP
我們知道tcp是在七層網路模型中的傳輸層,對於tcp的內容來講,大多數感興趣的都在它的那三次握手和四次揮手上了
那麼我們也簡單的說說看是怎麼回事吧
三次握手
為什麼要三次握手?
答: 為的是同步連線雙方的確認號和序列號,並且交換tcp視窗大小資訊
一句話:保證雙方收發都沒問題
握手過程如下:
- 建立連線
- 服務端收到客戶端發的SYN報文,確認序列號(SYN)併傳送確認號(ACK)
- 客戶端收到服務端發的SYN+ACK報文,傳送確認號(ACK),完成握手
四次揮手
為什麼要四次揮手?
一句話:雙方資料都傳送完畢了,都覺得可以斷開了
揮手過程如下:
- 客戶端向服務端傳送結束號(FIN)報文,請求關閉連線
- 服務端收到FIN報文,返回ACK報文,等待關閉
- 服務端看看資料發完沒有,直到資料都發完了,再返回FIN報文,請求關閉連線
- 客戶端收到FIN報文,傳送ACK報文讓服務端關閉連線,等一會看服務端沒反應了,自己也關閉連線
更直白的過程:
- 客戶端: 我要關閉連線了
- 服務端: 好的,稍等
- 服務端: 資料都給你了,可以關了
- 客戶端: 你關了,我就關
當然還有個總被提及的問題
- 為什麼握手是三次,但揮手卻是四次?
其實從上面直白的揮手過程就能發現
多了一次就是在“好的,稍等”那次,哈哈
CDN的作用
cdn想必工作中都有用到,概念什麼的就不再贅述了,總結了它的3點作用,畢竟我們不用太深入瞭解它的工作原理,知道作用就行了
- 快取
- 節省伺服器流量
- 最近節點優先
在瀏覽器位址列輸入URL,回車後發生了什麼
這種問題在回答方面可大可小,可深可淺,大致流程還是亙古不變的,只不過要看是不是想深究其因了
下面我就寫出來,我個人認為的過程吧
- DNS將URL解析為IP
- 有快取,直接返回快取
- 無快取,繼續遞迴解析
- DNS解析得到伺服器的IP,與伺服器建立TCP連線
- IP協議:選擇傳輸路線,負責找到
- TCP協議:三次握手、分片、可靠傳輸、重新傳送的機制
- 瀏覽器通過http協議傳送請求
- 請求行、請求頭、請求體
- 伺服器接收請求後,開始查庫,讀檔案,拼接要返回的http響應
- 瀏覽器收到html檔案開始渲染
- 解析html為dom樹,解析css為css-tree,最終生成render-tree渲染樹,阻塞渲染
- 遍歷渲染樹開始佈局,計算每個節點的大小位置資訊
- 將渲染樹每個節點繪製到頁面上
- 載入js檔案,執行js指令碼
- 迴流reflow和重繪repaint
就這麼10條吧,其實每一條都有可以深入展開的內容,不過我這裡就不一一介紹了,畢竟我也知道的甚少,就不裝腔作勢了,哈哈
點到為止
對於網路方面的知識我並不熟悉,也是在學習一點點的皮毛,分享給大家也是為了和大家一起進步
好了,就寫到這裡吧,感謝大家的觀看了,886