位元組一面:post 為什麼會發送兩次請求?被問懵了…

来源:https://www.cnblogs.com/javastack/archive/2023/10/26/17788643.html
-Advertisement-
Play Games

前言 最近博主在位元組面試中遇到這樣一個面試題,這個問題也是前端面試的高頻問題,因為在前端開發的日常開發中我們總是會與post請求打交道,一個小小的post請求也是牽扯到很多知識點的,博主在這給大家細細道來。 同源策略 在瀏覽器中,內容是很開放的,任何資源都可以接入其中,如 JavaScript 文件 ...


前言

最近博主在位元組面試中遇到這樣一個面試題,這個問題也是前端面試的高頻問題,因為在前端開發的日常開發中我們總是會與post請求打交道,一個小小的post請求也是牽扯到很多知識點的,博主在這給大家細細道來。

同源策略

在瀏覽器中,內容是很開放的,任何資源都可以接入其中,如 JavaScript 文件、圖片、音頻、視頻等資源,甚至可以下載其他站點的可執行文件。

但也不是說瀏覽器就是完全自由的,如果不加以控制,就會出現一些不可控的局面,例如會出現一些安全問題,如:

  • 跨站腳本攻擊(XSS)
  • SQL 註入攻擊
  • OS 命令註入攻擊
  • HTTP 首部註入攻擊
  • 跨站點請求偽造(CSRF)
  • 等等…

如果這些都沒有限制的話,對於我們用戶而言,是相對危險的,因此需要一些安全策略來保障我們的隱私和數據安全。

這就引出了最基礎、最核心的安全策略:同源策略。

推薦一個開源免費的 Spring Boot 實戰項目:

https://github.com/javastacks/spring-boot-best-practice

什麼是同源策略

同源策略是一個重要的安全策略,它用於限制一個源的文檔或者它載入的腳本如何能與另一個源的資源進行交互。

如果兩個 URL 的協議、主機和埠都相同,我們就稱這兩個 URL 同源。

協議:協議是定義了數據如何在電腦內和之間進行交換的規則的系統,例如 HTTP、HTTPS。

主機:是已連接到一個電腦網路的一臺電子電腦或其他設備。網路主機可以向網路上的用戶或其他節點提供信息資源、服務和應用。使用 TCP/IP 協議族參與網路的電腦也可稱為 IP 主機。

埠:主機是電腦到電腦之間的通信,那麼埠就是進程到進程之間的通信。

如下表給出了與 URL http://test.home.com:8080/dir/page.html 的源進行對比的示例:

同源策略主要表現在以下三個方面:DOM、Web 數據和網路。

  • DOM 訪問限制:同源策略限制了網頁腳本(如 JavaScript)訪問其他源的 DOM。這意味著通過腳本無法直接訪問跨源頁面的 DOM 元素、屬性或方法。這是為了防止惡意網站從其他網站竊取敏感信息。
  • Web 數據限制:同源策略也限制了從其他源載入的 Web 數據(例如 XMLHttpRequest 或 Fetch API)。在同源策略下,XMLHttpRequest 或 Fetch 請求只能發送到與當前網頁具有相同源的目標。這有助於防止跨站點請求偽造(CSRF)等攻擊。
  • 網路通信限制:同源策略還限制了跨源的網路通信。瀏覽器會阻止從一個源發出的請求獲取來自其他源的響應。這樣做是為了確保只有受信任的源能夠與伺服器進行通信,以避免惡意行為。

出於安全原因,瀏覽器限制從腳本內發起的跨源 HTTP 請求,XMLHttpRequest 和 Fetch API,只能從載入應用程式的同一個域請求 HTTP 資源,除非使用 CORS 頭文件

CORS

對於瀏覽器限制這個詞,要著重解釋一下:不一定是瀏覽器限制了發起跨站請求,也可能是跨站請求可以正常發起,但是返回結果被瀏覽器攔截了。

瀏覽器將不同域的內容隔離在不同的進程中,網路進程負責下載資源並將其送到渲染進程中,但由於跨域限制,某些資源可能被阻止載入到渲染進程。如果瀏覽器發現一個跨域響應包含了敏感數據,它可能會阻止腳本訪問這些數據,即使網路進程已經獲得了這些數據。CORB 的目標是在渲染之前儘早阻止惡意代碼獲取跨域數據。

CORB 是一種安全機制,用於防止跨域請求惡意訪問跨域響應的數據。渲染進程會在 CORB 機制的約束下,選擇性地將哪些資源送入渲染進程供頁面使用。

例如,一個網頁可能通過 AJAX 請求從另一個域的伺服器獲取數據。雖然某些情況下這樣的請求可能會成功,但如果瀏覽器檢測到請求返回的數據可能包含惡意代碼或與同源策略衝突,瀏覽器可能會阻止網頁訪問返回的數據,以確保用戶的安全。

跨源資源共用(Cross-Origin Resource Sharing,CORS)是一種機制,允許在受控的條件下,不同源的網頁能夠請求和共用資源。由於瀏覽器的同源策略限制了跨域請求,CORS 提供了一種方式來解決在 Web 應用中進行跨域數據交換的問題。

CORS 的基本思想是,伺服器在響應中提供一個標頭(HTTP 頭),指示哪些源被允許訪問資源。瀏覽器在發起跨域請求時會先發送一個預檢請求(OPTIONS 請求)到伺服器,伺服器通過設置適當的 CORS 標頭來指定是否允許跨域請求,並指定允許的請求源、方法、標頭等信息。

簡單請求

不會觸發 CORS 預檢請求。這樣的請求為 簡單請求,。若請求滿足所有下述條件,則該請求可視為 簡單請求:

  1. HTTP 方法限制:只能使用 GET、HEAD、POST 這三種 HTTP 方法之一。如果請求使用了其他 HTTP 方法,就不再被視為簡單請求。
  2. 自定義標頭限制:請求的 HTTP 標頭只能是以下幾種常見的標頭:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type(僅限於 application/x-www-form-urlencoded、multipart/form-data、text/plain)。HTML 頭部 header field 欄位:DPR、Download、Save-Data、Viewport-Width、WIdth。如果請求使用了其他標頭,同樣不再被視為簡單請求。
  3. 請求中沒有使用 ReadableStream 對象。
  4. 不使用自定義請求標頭:請求不能包含用戶自定義的標頭。
  5. 請求中的任意 XMLHttpRequestUpload 對象均沒有註冊任何事件監聽器;XMLHttpRequestUpload 對象可以使用 XMLHttpRequest.upload 屬性訪問

預檢請求

非簡單請求的 CORS 請求,會在正式通信之前,增加一次 HTTP 查詢請求,稱為 預檢請求。

需預檢的請求要求必須首先使用 OPTIONS 方法發起一個預檢請求到伺服器,以獲知伺服器是否允許該實際請求。預檢請求 的使用,可以避免跨域請求對伺服器的用戶數據產生未預期的影響。

例如我在自己的網站上刪除一條記錄:

它首先會發起一個預檢請求,預檢請求的頭信息包括兩個特殊欄位:

  • Access-Control-Request-Method:該欄位是必須的,用來列出瀏覽器的 CORS 請求會用到哪些 HTTP 方法,上例是 POST。
  • Access-Control-Request-Headers:該欄位是一個逗號分隔的字元串,指定瀏覽器 CORS 請求會額外發送的頭信息欄位,上例是 content-type,x-secsdk-csrf-token。
  • access-control-allow-origin:在上述例子中,表示 https://xxx.cn 可以請求數據,也可以設置為* 符號,表示統一任意跨源請求。
  • access-control-max-age:該欄位可選,用來指定本次預檢請求的有效期,單位為秒。上面結果中,有效期是 1 天(86408 秒),即允許緩存該條回應 1 天(86408 秒),在此期間,不用發出另一條預檢請求。

一旦伺服器通過了 預檢請求,以後每次瀏覽器正常的 CORS 請求,就都跟簡單請求一樣,會有一個 Origin 頭信息欄位。伺服器的回應,也都會有一個 Access-Control-Allow-Origin 頭信息欄位。

上面頭信息中,Access-Control-Allow-Origin 欄位是每次回應都必定包含的。

附帶身份憑證的請求與通配符

在響應附帶身份憑證的請求時:

  • 為了避免惡意網站濫用 Access-Control-Allow-Origin 頭部欄位來獲取用戶敏感信息,伺服器在設置時不能將其值設為通配符 *。相反,應該將其設置為特定的域,例如:Access-Control-Allow-Origin: https://xxx.cn。通過將 Access-Control-Allow-Origin 設置為特定的域,伺服器只允許來自指定域的請求進行跨域訪問。這樣可以限制跨域請求的範圍,避免不可信的域獲取到用戶敏感信息。
  • 為了避免潛在的安全風險,伺服器不能將 Access-Control-Allow-Headers 的值設為通配符 *。這是因為不受限制的請求頭可能被濫用。相反,應該將其設置為一個包含標頭名稱的列表,例如:Access-Control-Allow-Headers: X-PINGOTHER, Content-Type。通過將 Access-Control-Allow-Headers 設置為明確的標頭名稱列表,伺服器可以限制哪些自定義請求頭是允許的。只有在允許的標頭列表中的頭部欄位才能在跨域請求中被接受。
  • 為了避免潛在的安全風險,伺服器不能將 Access-Control-Allow-Methods 的值設為通配符 *。這樣做將允許來自任意域的請求使用任意的 HTTP 方法,可能導致濫用行為的發生。相反,應該將其設置為一個特定的請求方法名稱列表,例如:Access-Control-Allow-Methods: POST, GET。通過將 Access-Control-Allow-Methods 設置為明確的請求方法列表,伺服器可以限制哪些方法是允許的。只有在允許的方法列表中的方法才能在跨域請求中被接受和處理。
  • 對於附帶身份憑證的請求(通常是 Cookie),

這是因為請求的標頭中攜帶了 Cookie 信息,如果 Access-Control-Allow-Origin 的值為 *,請求將會失敗。而將 Access-Control-Allow-Origin 的值設置為 https://xxx.cn,則請求將成功執行。

另外,響應標頭中也攜帶了 Set-Cookie 欄位,嘗試對 Cookie 進行修改。如果操作失敗,將會拋出異常。

完整的請求流程圖

總結

預檢請求是在進行跨域資源共用 CORS 時,由瀏覽器自動發起的一種 OPTIONS 請求。它的存在是為了保障安全,並允許伺服器決定是否允許跨域請求。

跨域請求是指在瀏覽器中向不同功能變數名稱、不同埠或不同協議的資源發送請求。

出於安全原因,瀏覽器預設禁止跨域請求,只允許同源策略。而當網頁需要進行跨域請求時,瀏覽器會自動發送一個預檢請求,以確定是否伺服器允許實際的跨域請求。

預檢請求中包含了一些額外的頭部信息,如 Origin 和 Access-Control-Request-Method 等,用於告知伺服器實際請求的方法和來源。伺服器收到預檢請求後,可以根據這些頭部信息,進行驗證和授權判斷。如果伺服器認可該跨域請求,將返回一個包含 Access-Control-Allow-Origin 等頭部信息的響應,瀏覽器才會繼續發送實際的跨域請求。

使用預檢請求機制可以有效地防範跨域請求帶來的安全風險,保護用戶數據和隱私。

版權聲明:本文為CSDN博主「程式員小豪」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/A_D_H_E_R_E/article/details/132483843

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了。。。

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發佈,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文主要針對的自己寫的包無法正常import的情況,如果是第三方包的話正常來說沒有問題。 第三方包 主要考慮沒有安裝對應的版本以及包名寫錯了等奇葩情況,具體可參考ModuleNotFoundError: No module named ‘xxx’可能的解決方案大全 自建的包 如果是自己的包,可按照下 ...
  • 9.1、環境搭建 9.1.1、在project創建新module 9.1.2、選擇maven 9.1.3、設置module名稱和路徑 9.1.4、module初始狀態 9.1.5、配置打包方式和引入依賴 註意:預設的打包方式為 jar,為了能配置web資源,需要將打包方式設置為 war <?xml ...
  • 1. maven打包方式 maven打包有三種方式 pom、jar、war。在pom.xml 文件中聲明的方式分別如下: <!-- 1. pom方式 --> <packaging>pom</packaging>` <!-- 2. jar方式 --> <packaging>jar</packaging ...
  • 不,代碼是值錢的! 前幾天我們一直服務的一個客戶覺得自己用了兩三年的UI太醜,乞求我們換一套。集團領導討論後一口報價30w,牛逼哄哄說:很麻煩的啊,要先設計UI庫,然後把所有頁面都換個樣,又要測試這玩意(內行人都明白前端能測出啥bug,也就可能要考慮優化),大概要6個人做一個月。 然後我這架構大頭兵 ...
  • 說明 介紹 該腳本使用Selenium庫來實現自動登錄併在指定的時間購買商品。 運行前準備 mac 的safari瀏覽器本身已經集成了safaridriver,只要啟用並開啟即可,步驟如下: 終端啟用safaridriver: sudo safaridriver --enable 嘗試運行safra ...
  • 在查找二叉樹某個節點時,如果把二叉樹所有節點理理解為解空間,待找到那個節點理解為滿足特定條件的解,對此解答可以抽象描述為: _在解空間中搜索滿足特定條件的解_,這其實就是搜索演算法(Search)的一種描述。當然也有其他描述,比如是“指一類用於在數據集合中查找特定項或解決問題的演算法”,又或者是“指通過... ...
  • 相信大家對python-docx這個常用的操作docx文檔的庫都不陌生,它支持以內聯形狀(Inline Shape)的形式插入圖片,即圖片和文本之間沒有重疊,遵循流動版式(flow layout)。但是,截至最新的0.8.10版本,python-docx尚不支持插入浮動圖片(floating pic ...
  • Bean在Spring中的定義是_org.springframework.beans.factory.config.BeanDefinition_介面,BeanDefinition裡面存儲的就是我們編寫的Java類在Spring中的元數據 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...