每日八股-6.12
- 計算機網絡
- 1.當我們在瀏覽器中輸入一個 URL 并按下回車后,到頁面最終顯示出來,這中間都發生了哪些關鍵步驟?
- 2.請簡述一下 JWT(JSON Web Tokens)的原理和校驗機制
- 3.DNS 是如何進行域名解析的?它屬于 OSI 哪一層的協議?
- 4.HTTP 協議定義了哪些常用的請求方法?你的項目中用了哪些?
- 5.HTTP 協議有哪些常見的狀態碼?你能說出一些你熟悉的嗎?
- 6.HTTP 協議是長連接還是短連接呢?長連接的好處了解嗎?
- 7.HTTP/1.0 和 HTTP/1.1 之間有哪些主要的區別?
- 8.Cookie、Session 和 Token 這三種技術有什么異同之處?它們分別適用于哪些場景?
- 9.什么是跨域?在什么情況下會發生跨域請求?
計算機網絡
1.當我們在瀏覽器中輸入一個 URL 并按下回車后,到頁面最終顯示出來,這中間都發生了哪些關鍵步驟?
首先,我們需要解析瀏覽器客戶端的URL,因為網絡傳輸需要ip地址,一個正確的URL包括協議,比如http,https,ftp;域名,比如www.baidu.com;端口,對于http來說,默認端口是80,對于https來說,默認端口是443;路徑,比如說我們像訪問百度貼吧里面某一個具體的帖子,那么后面一定會跟隨一個具體的路徑。
解析出這些之后,我們需要獲得請求的ip地址,首先我們需要查看瀏覽器的緩存是否有這個ip地址,如果有直接返回,如果沒有,我們接下來去查操作系統的緩存,比如hosts,看有沒有ip地址,如果有,直接返回,如果沒有,我們就要用到域名解析協議,也就是DNS,本地域名服務器會幫我們去遞歸的查詢ip地址。首先,去查根域名服務器,然后去查頂級域名服務器,最后去查權威域名服務器,這樣我們就得到了ip地址。
得到了ip地址之后,我們就可以與服務器建立TCP連接,如果使用的協議是http的話,那么我們用三次握手來建立TCP連接,具體細節是首先客戶端發送一個SYN包到服務器,表示我要開始與你建立連接了,然后服務器返回一個SYN ACK包表示服務器收到了來自客戶端的建立連接請求,之后客戶端再發送一個ACK包表示收到了來自服務器的SYN ACK包,可以正式開始傳輸數據了。如果使用的協議是https的話,那么我們用四次握手來建立安全的TCP連接。
在完成了建立連接后,瀏覽器將之前的http報文逐層的向下傳輸并封裝該層的特定信息,比如說到傳輸層就要封裝上源端口和目的端口;到網絡層就要封裝上源ip和目的ip;到數據鏈路層就要封裝上源mac地址和目的mac地址,另外,在數據鏈路層,我們會使用到ARP協議來廣播請求,以此來知道下一跳的目標mac地址。
就這樣,我們經過了無數個路由器最終到達了目的服務器,服務器通過與剛才相反的路徑返回我們請求的資源,在瀏覽器web頁面上渲染出來,呈現給用戶。
2.請簡述一下 JWT(JSON Web Tokens)的原理和校驗機制
JWT的全稱是JSON WEB TOKENS,是一種基于Json的開放標準,一個JWT由三個部分構成
-
頭部(header)
頭部包括兩個字段,第一個字段是alg,也就是指明我們的加密算法,分為對稱算法和非對稱算法兩種,對稱算法用到的一般是HS256,非對稱算法一般用到的是RS256;第二個字段是typ,這是一個固定值JWT,用來表示他是一個jwt token。頭部會使用base64 url來進行編碼,并進行加密
-
負載(payload)
負載主要存儲的是實際信息,包括用戶登錄信息,過期時間等等,他也需要用base64 url來進行編碼,但是他不會加密,所以說我們不能將任何敏感的數據存放在負載里。
-
簽名(signature)
簽名是服務器用來驗證客戶端傳來的jwt的完整性和真實性,它等于alg(解密后的頭部+“.”+解密后的負載+secret)
校驗機制是這樣的:客戶端發來一個jwt token,服務器端用頭部中的算法計算base64 url解密后的頭部加上base64 url解密后的負載加上服務器端的密鑰,看是否用jwt token中的簽名一致,如果一致,說明沒有被篡改,可以進行后續的操作。
補充Refresh Token
為什么需要Refresh Token?
- Access Token,即jwt,在客戶端請求服務器時,會頻繁的暴露在網絡傳輸中,極有可能會被竊取,如果說jwt token設置的過期時間很長,那么對用戶會造成損失
- 如果jwt token設置的過期時間很短,比如說15分鐘,那么用戶在使用服務的時候,每隔十五分鐘就需要重新輸入一次密碼,這對于用戶的體驗感是極差的
所以說,我們在Access Token的基礎上,引入了Refresh Token,它解決了上面兩個問題,首先,Access Token通常存儲在內存中,而Refresh Token一般存在cookie上,這保證了安全性,另外最重要的是我們引入Refresh Token來刷新Access Token的這一過程,對用戶是無感的,也就是用戶不會察覺到。
Access Token (訪問令牌):就像是你酒店房間的房卡。它的有效期很短(比如 15 分鐘到 1 小時),你每次進房間(訪問受保護的 API)都需要出示它。它直接暴露給各種服務,風險較高。
Refresh Token (刷新令牌):就像是你辦理入住時拿到的入住憑證。它的有效期很長(比如 7 天或 30 天),你平時都把它妥善保管起來,不會輕易示人。它的唯一作用就是,當你的房卡(Access Token)過期失效時,你可以拿著這個憑證去前臺(特定的刷新接口),換一張新的房卡。
所以,Refresh Token 本身并不用于訪問業務 API,它唯一的作用就是用來獲取新的 Access Token。
3.DNS 是如何進行域名解析的?它屬于 OSI 哪一層的協議?
DNS屬于應用層的協議。
當我們在瀏覽器輸入一個url后,瀏覽器首先檢查自己的緩存,看有無對應的ip地址,有就直接返回,沒有就去檢查操作系統的緩存,如果還沒有,本地域名服務器先檢查自己的緩存,如果沒有就去遞歸的搜尋ip,首先去根域名服務器,根域名服務器會告訴本地域名服務器去哪個頂級域名服務器找,然后去頂級域名服務器,頂級域名服務器會告訴本地域名服務器去哪個權威域名服務器找,最后到權威域名服務器找到需要的ip地址,并逐層向上返回。
這時本地域名服務器會將ip緩存下來,以便于下一次訪問同樣的url,瀏覽器和操作系統也可能將ip緩存下來。
4.HTTP 協議定義了哪些常用的請求方法?你的項目中用了哪些?
我了解到的有GET、PUT、POST、HEAD、DELETE請求。
GET請求用于從服務器獲取資源, PUT請求用于將請求體中的內容更新到服務器上,POST請求用于往服務器添加資源,HEAD請求只會獲取資源的頭部信息,DELETE請求用于從服務器刪除資源。
項目中用到的請求是GET和POST請求。
5.HTTP 協議有哪些常見的狀態碼?你能說出一些你熟悉的嗎?
- 2開頭的狀態碼,表示服務器已成功接收到請求,常見的有200 OK
- 3開頭的狀態碼,表示客戶端需要進一步的操作才能訪問資源,通常是重定向,常見的比如301 Moved permanently,表示永久重定向
- 4開頭的狀態碼,表示客戶端錯誤,常見的比如說403 forbidden,表示服務器禁止訪問該資源,404 not found,表示服務器找不到該資源
- 5開頭的狀態碼,表示服務器錯誤,常見的比如說500 internal server error,表示服務器內部錯誤,502 bad gateway,表示服務器作為網關時,從后端服務器收到了無效響應
6.HTTP 協議是長連接還是短連接呢?長連接的好處了解嗎?
這個要區分http/1.0和http/1.1
如果是http/1.0,默認的就是短鏈接,也就是說客戶端完成了一次對服務器的請求,該連接就會關閉,除非顯式在請求頭中指定connection keep alive。
如果是http/1.1,默認的就是長連接,除非顯式指定connection close,長連接的好處就是客戶端要多次訪問同一url時,不需要多次的建立連接,只需在第一次建立連接就可以,沒有了多次建立和關閉連接的開銷,提升了通信的效率和性能。
7.HTTP/1.0 和 HTTP/1.1 之間有哪些主要的區別?
- 最關鍵的一點,1.1默認長連接,1.0默認短鏈接,長連接可以減少頻繁創建和關閉TCP連接的開銷,提升網絡通信性能和效率
- 1.1支持管道化請求傳輸,1.0只能等待一個請求返回響應之后,再傳輸下一個請求,但1.1可以在一個連接上發送多個請求,但需要保證返回響應的順序,這會造成隊頭阻塞
隊頭阻塞:比如說連接上有三個請求,第一個請求要訪問一個很大的數據文件,預估耗時3秒,第二個請求只需要訪問一段文字,預計耗時0.01秒,第三個請求只要訪問一張圖片,預計耗時0.01秒,因為要保證返回響應的順序性,即使我的后續請求只需要很短時間完成,那么也需要等待前面的請求先返回響應,這就是隊頭阻塞
- 1.1引入了更多的緩存控制,比如Entity Tag,If-Match等等
- 1.1針對帶寬進行了優化,允許只訪問服務器的部分資源,這可以保證用戶在下載大文件的斷點續傳功能
- 1.1支持虛擬主機,通過引入host頭部字段,可以明確指定要訪問的域名;1.0的一大缺陷就是服務器只知道要訪問的ip地址,但不知道具體的域名是什么,如果說一臺服務器上托管了多個網站,服務器就無法區分請求是發給哪個網站的。
8.Cookie、Session 和 Token 這三種技術有什么異同之處?它們分別適用于哪些場景?
Cookie存儲在客戶端(瀏覽器),它主要用來存儲一些非敏感的數據,比如說用戶偏好等,安全性低,默認不支持跨域
Session存儲在服務器端,服務器會為每一個發來請求的客戶維護一個唯一的session ID,并通過cookie發給客戶端,安全性較高,跨域的支持有限,可能需要一些特殊方法實現跨域
Token存儲在客戶端,它包含客戶的一些登錄信息和權限信息,服務器可以通過驗證token來進行用戶的登錄和授權,token會使用算法加密,安全性高,且支持跨域
從適用場景來看,Cookie適用于存儲一些臨時數據,做簡單的狀態管理;Session適用于傳統的web應用,需要保護用戶的敏感信息;Token則適用于現代的web應用和Restful Api,尤其是需要跨域和無狀態服務的場景。
9.什么是跨域?在什么情況下會發生跨域請求?
跨域指的是在瀏覽器環境下,去訪問不同源的資源,這里的源包括域名,協議,端口。
以下場景都會發生跨域請求
- 當前協議是http,要去訪問https下的資源
- 當前域名是example.com,要去訪問example2.com的資源
- 當前端口是默認端口80,要去訪問端口8080的資源
一個現實場景中的例子就是現在的前后端分離項目,前端應用部署在一個域名之下,而后端的api服務部署在另一個域名之下,當前端通過fetch發送請求,比如說獲取用戶列表或者提交表單數據,這時就發生了跨域請求,解決方案之一是后端服務器會在響應頭中添加Access-Control-Allow-Origin: http://www.my-frontend-app.com(前端域名) 來允許前端域名訪問。