前端面試之計算機網路

我不吃餅乾呀發表於2022-01-27

1. HTTP 和 HTTPS

定義

  超文字傳輸協議(HyperText Transfer Protocol,HTTP)是一種用於分散式、協作式和超媒體資訊系統的應用層協議。HTTP是全球資訊網的資料通訊的基礎。

  HTTPS 是一種通過計算機網路進行安全通訊的傳輸協議,經由 HTTP 進行通訊,利用 SSL/TLS 建立全通道,加密資料包。HTTPS使用的主要目的是提供對網站伺服器的身份認證,同時保護交換資料的隱私與完整性。

區別

  • HTTPS 協議需要到 CA 申請證照,一般免費證照很少,需要交費。
  • HTTP 是超文字傳輸協議,資訊是明文傳輸,HTTPS 則是具有安全性的 SSL 加密傳輸協議。
  • HTTP 和 HTTPS 使用的是完全不同的連線方式,用的埠也不一樣,前者是80,後者是443。
  • HTTP 的連線很簡單,是無狀態的;HTTPS 協議是由 SSL+HTTP 協議構建的可進行加密傳輸、身份認證的網路協議,比 HTTP 協議安全。

SSL 握手過程

HTTPS 的故事

  • 客戶端給出協議的版本號、一個客戶端生成的隨機數和客戶端支援的加密演算法;
  • 服務端在客戶端給出的加密演算法列表中選出一種,並給出數字證照和一個服務端生成的額隨機數;
  • 客戶端確認數字證照的有效性,然後生成一個新的隨機數,並使用數字證照中的公鑰加密這個隨機數;
  • 服務端使用私鑰解密,獲取客戶端發來的隨機數;
  • 客戶端和服務端根據約定的加密方法,使用之前的三個隨機數,生成對話金鑰,這個金鑰會用來加密接下來的整個通訊過程

2. TCP 三次握手

TCP沒那麼難吧?

image.png

3. TCP 和 UDP

  • TCP 面向連線,UDP 是無連線的,即傳送資料之前不需要建立連線。
  • TCP 提供可靠的服務。也就是說,通過TCP連線傳送的資料,無差錯,不丟失,不重複,且按序到達;UDP 盡最大努力交付,即不保證可靠交付。
  • TCP 面向位元組流,實際上是 TCP 把資料看成一連串無結構的位元組流;UDP 是面向報文的。UDP 沒有擁塞控制,因此網路出現擁塞不會使源主機的傳送速率降低(對實時應用很有用,如 IP 電話,實時視訊會議等)。
  • 每一條 TCP 連線只能是點到點的;UDP 支援一對一,一對多,多對一和多對多的互動通訊。
  • TCP 首部開銷 20 位元組;UDP 的首部開銷小,只有 8 個位元組。
  • TCP 的邏輯通訊通道是全雙工的可靠通道,UDP則是不可靠通道。

4. WebSocket

  • WebSocket 是 HTML5 中的協議,支援持久連續,HTTP 協議不支援永續性連線。
  • WebSocket 是基於 HTTP 協議的,或者說借用了 HTTP 協議來完成一部分握手,在握手階段 與 HTTP 是相同的。指定兩個屬性,upgradeconnection
    Upgrade: websocket
    Connection: Upgrade
    

5. HTTP1.0/HTTP1.1/HTTP2/HTTP3

HTTP1.0 和 HTTP1.1

  • HTTP1.0 中主要使用 header 裡的 If-Modified-SinceExpires 來做為快取判斷的標準,HTTP1.1 則引入了更多的快取控制策略例如 Entity tagIf-Unmodified-Since, If-Match, If-None-Match 等更多可供選擇的快取頭來控制快取策略。
  • HTTP 1.1 支援長連線(PersistentConnection)和請求的流水線(Pipelining)處理,在一個 TCP 連線上可以傳送多個 HTTP 請求和響應,減少了建立和關閉連線的消耗和延遲,在 HTTP1.1 中預設開啟 Connection:keep-alive,一定程度上彌補了 HTTP1.0 每次請求都要建立連線的缺點。

HTTP1 和 HTTP2.0

HTTP1 缺點

  1. TCP連線數限制 (可通過域名分片解決)
  2. 頭部阻塞
  3. 明文傳輸不安全

HTTP2

  • 二進位制分幀,幀是資料傳輸的最小單位,以二進位制傳輸代替原本的明文傳輸,原本的報文訊息被劃分為更小的資料幀
  • 首部壓縮
  • 多路複用
  • 服務端推送

HTTP3

QUIC協議(全稱Quick UDP Internet Connections,快速UDP網際網路連線)

  • 實現了類似TCP的流量控制、傳輸可靠性的功能。
  • 整合了TLS加密功能。
  • 實現了HTTP/2中的多路複用功能。

6. HTTP 狀態碼

  • 1xx:訊息,請求已被伺服器接收,繼續處理
  • 2xx:成功,請求已成功被伺服器接收、理解、並接受
  • 3xx:重定向,需要後續操作才能完成這一請求
    • 301 永久移動
    • 302 臨時移動
    • 304 未修改,使用快取
  • 4xx:請求錯誤,請求含有詞法錯誤或者無法被執行
    • 401 需要認證
    • 403 無許可權
    • 404 未找到
    • 405 方法不被允許
  • 5xx:伺服器錯誤,伺服器在處理某個正確請求時發生錯誤

7. HTTP 常用請求頭

  • Accept 可接受的相應內容型別
  • Accept-Charset 可接受的字符集
  • If-Modified-Since、If-None-Match 未修改返回304
  • 還有很多……待補充 TODO

8. 強快取、協商快取

前端優化:瀏覽器快取技術介紹

快取好處

(1)減少頁面載入時間;(2)減少伺服器負載;

強快取

瀏覽器在載入資源時,先判斷它是否命中強快取,強快取如果命中,瀏覽器直接從自己的快取中讀取資源,不會發請求到伺服器

HTTP1.0 - Expires

請求資源時伺服器會返回 Expires,(比如expires: Fri, 01 Jan 2021 00:00:00 GMT)下次請求前用 Expires 跟當前的請求時間比較,如果請求時間在 Expires 指定的時間之前,就能命中快取,否則從伺服器載入資源。缺點是客戶端時間和伺服器時間有誤差。

HTTP1.1 - Cache-Control

伺服器返回 Cache-Control,這是一個相對時間,表示快取有效期,單位秒。(比如:cache-control: max-age=1800, s-maxage=60 其中 s-maxage 一般應用於快取伺服器)。

協商快取

當瀏覽器對某個資源的請求沒有命中強快取,就會發一個請求到伺服器,驗證協商快取是否命中,如果協商快取命中,請求響應返回 304 Not Modified

Last-Modified,If-Modified-Since

伺服器返回資源會返回 Last-Modified,表示這個資源在伺服器上的最後修改時間。(比如:last-modified: Tue, 18 Jan 2022 02:52:12 GMT),下次請求客戶端就會加上請求頭 If-Modified-Since,且對應值會伺服器返回的時間(if-modified-since: Tue, 18 Jan 2022 02:52:12 GMT)。

伺服器再次收到資源請求時,根據瀏覽器傳過來 If-Modified-Since 和資源在伺服器上的最後修改時間判斷資源是否有變化,如果沒有變化則返回 304 Not Modified,但是不會返回資源內容;如果有變化,就正常返回資源內容。

缺點是有時檔案改動但是時間沒有修改(間隔時間過短),或者時間修改但是並沒有改動檔案。

HTTP1.1 - ETag、If-None-Match

伺服器返回 ETag 用於標記檔案,當 ETag 修改時表示檔案被修改。(如:etag: 2e681a-6-5d044840

瀏覽器請求時會傳送 If-None-Match 和上一次返回的 ETag,伺服器根據兩次 ETag 判斷是否是最新檔案。

禁止快取

請求時可以禁止快取,cache-control: no-cache, no-store

no-cache 表示每次請求資源都會向瀏覽器傳送請求(即取消強快取),no-store 取消快取。

public 和 private

Cache-Control 可以指定 public 或 privateprivate 表示為使用者個人資訊,不能在快取伺服器快取。

9. HTTP 支援方法

GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE, CONNECT

10. GET 和 POST 區別

【前端 · 面試 】HTTP 總結(五)—— GET 和 POST

  • GET 多用於從服務端獲取資源,POST 一般用來向服務端提交資源
  • GET 一般用URL傳參,由於 URL 長度限制引數長度有限制,POST 引數可以放在 body 中,無長度限制。
  • 引數的資料型別,GET 只接受 ASCII 字元,而 POST 沒有限制。
  • GET 請求只能進行 URL 編碼,POST 支援多種編碼方式。
  • GET 請求會被瀏覽器主動 cache,而 POST 不會,除非手動設定。

11. 在位址列裡輸入一個 URL,到這個頁面呈現出來,中間會發生什麼?

輸入url按回車後發生的一系列不可描述的事情

  1. DNS 解析
    域名解析為 IP 地址,瀏覽器快取-->作業系統快取-->訪問 DNS 伺服器
  2. TCP 連線
    三次握手、四次揮手
  3. HTTP 請求
    強快取、協商快取
  4. 服務端處理請求,HTTP 響應返回
    返回碼
  5. 瀏覽器拿到響應資料,解析響應內容,把解析的結果展示給使用者
    DOM樹、CSSOM樹、Render樹、迴流、重繪

12. XSS 和 CSRF

前端安全系列(一):如何防止XSS攻擊?
前端安全系列之二:如何防止CSRF攻擊?

XSS

Cross-Site Scripting(跨站指令碼攻擊) 簡稱 XSS,是一種程式碼注入攻擊。攻擊者通過在目標網站上注入惡意指令碼,使之在使用者的瀏覽器上執行。利用這些惡意指令碼,攻擊者可獲取使用者的敏感資訊如 Cookie、SessionID 等,進而危害資料安全。

XSS 的本質是:惡意程式碼未經過濾,與網站正常的程式碼混在一起;瀏覽器無法分辨哪些指令碼是可信的,導致惡意指令碼被執行。

XSS 分類

根據攻擊的來源,XSS 攻擊可分為儲存型、反射型和 DOM 型三種。

型別 儲存區* 插入點*
儲存型 XSS 後端資料庫 HTML
反射型 XSS URL HTML
DOM 型 XSS 後端資料庫/前端儲存/URL 前端 JavaScript
  • 儲存區:惡意程式碼存放的位置。
  • 插入點:由誰取得惡意程式碼,並插入到網頁上。

前兩種屬於伺服器安全漏洞,DOM 型 XSS 由前端取出惡意程式碼並執行,屬於前端漏洞。

XSS 攻擊的預防

  • 輸入過濾
  • 改成純前端渲染,把程式碼和資料分隔開
  • 不要把不可信的資料作為 HTML 插到頁面上、對 HTML 做充分轉義
  • 不要在 JavaScript 中執行不信任的字串,比如 eval()
  • Content Security Policy、輸入內容長度控制、HTTP-only Cookie、驗證碼

CSRF

CSRF(Cross-site request forgery)跨站請求偽造:攻擊者誘導受害者進入第三方網站,在第三方網站中,向被攻擊網站傳送跨站請求。利用受害者在被攻擊網站已經獲取的註冊憑證,繞過後臺的使用者驗證,達到冒充使用者對被攻擊的網站執行某項操作的目的。CSRF 攻擊針對狀態改變請求,而不是盜竊資料,因為攻擊者無法檢視對偽造請求的響應。

典型攻擊方式:在 b.com 向 a.com 傳送請求,會帶上 a.com 的 cookie。

CSRF的特點

  • 攻擊一般發起在第三方網站,而不是被攻擊的網站。
  • 攻擊利用受害者在被攻擊網站的登入憑證,冒充受害者提交操作;而不是直接竊取資料。
  • 整個過程攻擊者並不能獲取到受害者的登入憑證,僅僅是“冒用”。
  • 跨站請求可以用各種方式:圖片URL、超連結、CORS、Form提交等等。部分請求方式可以直接嵌入在第三方論壇、文章中,難以進行追蹤。

防護策略

  • 同源檢測:通過 Origin Header 或 Referer Header 確定來源域名
  • CSRF Token
  • 雙重Cookie驗證
  • Samesite Cookie屬性:Samesite=Strict 表示 cookie 不可作為第三方 cookie

13. Cookie/Session/sessionStorage/localStorage/IndexDB

  • Cookie 資料始終在同源的 HTTP 請求中攜帶(即使不需要),即 Cookie 在瀏覽器和伺服器間來回傳遞。而 sessionStorage 和 localStorage 不會自動把資料發給伺服器,僅在本地儲存。Cookie 資料還有路徑(path)的概念,可以限制 Cookie 只屬於某個路徑下,儲存的大小很小隻有4K左右。
  • sessionStorage 僅在當前瀏覽器視窗關閉前有效,localStorage 始終有效,視窗或瀏覽器關閉也一直儲存,因此用作持久資料,Cookie 只在設定的 Cookie 過期時間之前一直有效,即使視窗或瀏覽器關閉。
  • localStorage 和 Cookie 在所有同源視窗中都是共享的。但是不同頁面或標籤頁間無法共享 sessionStorage 的資訊。
  • IndexDB 是一個執行在瀏覽器上的非關係型資料庫。理論上來說,IndexDB 是沒有儲存上限的(一般來說不會小於 250M)。它不僅可以儲存字串,還可以儲存二進位制資料。
  • Session 是儲存在伺服器的鍵值對,一般把 SessionId 存在 Cookie 中,通過 SessionId 可以查詢對應物件。

14. SSO 單點登入

前端鑑權的兄弟們:cookie、session、token、jwt、單點登入

在提供標記的介面,通過 HTTP 返回頭的 Set-Cookie 欄位,直接「種」到瀏覽器上;瀏覽器發起請求時,會自動把 cookie 通過 HTTP 請求頭的 Cookie 欄位,帶給介面

  • Domain / Path 限制 cookie 的域名/路徑
  • Expires / Max-Age 指定 cookie 的有效期
  • Secure / HttpOnly Secure 屬性指定瀏覽器只有在加密協議 HTTPS 下,才能將這個 Cookie 傳送到伺服器。HttpOnly 屬性指定該 Cookie 無法通過 JavaScript 指令碼拿到。
  • HTTP 頭對 cookie 的讀寫 一個 Set-Cookie 頭用於向瀏覽器寫入一條 cookie,設定多個 cookie 需要設定多條
    Set-Cookie: username=jimu; domain=jimu.com; path=/blog; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

Session

  • 使用者登入,服務端把使用者登入狀態存為 Session,生成一個 sessionId,把 sessionId set 到 cookie 上
  • session 儲存方式,記憶體、資料庫、Redis

Token

  • 把登入資訊加密存為 token,並 set 到 cookie 中,介面校驗 token 有效性。
  • JSON Web Token (JWT) 是一個開放標準,定義了一種傳遞 JSON 資訊的方式。這些資訊通過數字簽名確保可信。
  • access token 用來訪問業務介面,由於有效期足夠短,盜用風險小,也可以使請求方式更寬鬆
  • refresh token 用來獲取 access token,有效期可以長一些,通過獨立服務和嚴格的請求方式增加安全性;由於不常驗證,也可以如前面的 session 一樣處理

單點登入 (SSO, Single Sign On)

  • 使用者進入 A 系統,沒有登入憑證(ticket),A 系統給他跳到 SSO
  • SSO 沒登入過,也就沒有 sso 系統下沒有憑證(注意這個和前面 A ticket 是兩回事),輸入賬號密碼登入
  • SSO 賬號密碼驗證成功,通過介面返回做兩件事:一是種下 sso 系統下憑證(記錄使用者在 SSO 登入狀態);二是通過一個帶 code 的 URL 重定向到系統 A 的介面上,這個介面通常在 A 向 SSO 註冊時約定
  • 瀏覽器被重定向到 A 域下,帶著 code 訪問了 A 的 callback 介面,callback 介面通過 code 換取 ticket
  • 這個 code 不同於 ticket,code 是一次性的,暴露在 URL 中,只為了傳一下換 ticket,換完就失效
  • callback 介面拿到 ticket 後,在自己的域下 set cookie 成功
  • 客戶端拿到 ticket,儲存起來,帶著請求系統 A 介面
  • 系統 A 校驗 ticket,成功後正常處理業務請求
  • 此時使用者第一次進入系統 B,沒有登入憑證(ticket),B 系統給他跳到 SSO
  • SSO 登入過,統一順序訪問 B 系統

15. 跨域問題

同源策略 SOP(Same origin policy)

同源指:協議相同、域名相同、埠相同。如果非同源,共有三種行為受到限制:

  • Cookie、LocalStorage 和 IndexDB 無法讀取。
  • DOM 和 JS 物件無法獲得
  • AJAX 請求不能傳送。

跨域解決方案

  • JSONP
  • WebSocket
  • CORS
  • 代理

跨域資源共享 CORS

瀏覽器將 CORS 請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。

簡單請求

滿足下面兩個條件的是簡單請求:

  • 請求方法是以下三種方法之一:HEAD、GET、POST
  • HTTP的頭資訊不超出以下幾種欄位:
    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type:只限於三個值 application/x-www-form-urlencodedmultipart/form-datatext/plain

瀏覽器發現這次跨源AJAX請求是簡單請求,就自動在頭資訊之中,新增一個 Origin 欄位,用來說明,本次請求來自哪個源(協議 + 域名 + 埠)。伺服器根據這個值,決定是否同意這次請求。

伺服器返回:

  • Access-Control-Allow-Origin: * 表示接受的域名,* 表示任意域名
  • Access-Control-Allow-Credentials: true 表示是否允許傳送Cookie
  • Access-Control-Expose-Headers 指定前端可以獲取的返回頭欄位
withCredentials

如果前端要傳送 cookie 需要指定

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

同時伺服器需要設定 Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin 不能為 *

非簡單請求

不滿足簡單請求條件的為非簡單請求。非簡單請求的 CORS 請求,會在正式通訊之前,增加一次HTTP查詢請求,稱為"預檢"請求(preflight)。

瀏覽器先詢問伺服器,當前網頁所在的域名是否在伺服器的許可名單之中,以及可以使用哪些 HTTP 動詞和頭資訊欄位。只有得到肯定答覆,瀏覽器才會發出正式的 XMLHttpRequest 請求,否則就報錯。

Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header

服務端返回

Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000 # 可選,用來指定本次預檢請求的有效期,單位為秒

相關文章