LiteHub中間件之跨域訪問CORS

跨域訪問CORS

    • 原理
      • 基本概念
      • 簡單請求
      • 非簡單請求(預檢請求)
    • 代碼實現
      • 服務器端Cors的關鍵配置
      • 服務端解析預檢請求
      • 服務端填充響應
    • 抓包分析

原理

基本概念

在瀏覽器安全模型中,同源策略是最重要的安全基石。
一個“域”是由3個要素組成的:

  • 協議(如:http 或 https)
  • 主機(Host,如 www.example.com 或 127.0.0.1)
  • 端口(Port,如 80 或 8080)

只要這三個完全一致,就是同源的。
例如

  • http://example.com:80 和 http://example.com:8080 是不同源
  • http://example.com 和 https://example.com 是不同源

下面是官網解釋跨域的圖解:
在這里插入圖片描述

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

簡單請求

按照 W3C 的 CORS 規范,只有完全滿足「安全要求」的跨域請求,瀏覽器才會把它直接當成簡單請求,直接發送給服務端,不需要先發 OPTIONS。
必須同時滿足以下條件

  1. 請求方法必須是(GET/HEAD/POST)三者之一
  2. 請求頭不能超出以下幾個字段(Accept、Accept-Language、Content-Language、Content-Type)等
  3. Content-Type(如果存在的話),其值只能是application/x-www-form-urlencoded、multipart/form-data、text/plain

非簡單請求(預檢請求)

非簡單請求是指那些對服務器有特殊要求的請求,例如:

  • 使用PUT或DELETE方法
  • 設置Content-Type為application/json
    即不滿足簡單請求的條件的都是預檢請求(非簡單請求)。

對于這類請求,瀏覽器會在正式通信前額外發送一次HTTP查詢請求(即預檢請求),這個過程叫做預檢(Preflight)。該請求會確認:

  1. 當前網頁域名是否在服務器的許可名單中
  2. 允許使用的HTTP方法和頭信息字段
    只有在獲得服務器肯定答復后,瀏覽器才會發出正式的XMLHttpRequest請求,否則將報錯。

“預檢請求”用的請求方法是 OPTIONS,表示這個請求是用來詢問的。頭信息里面,關鍵字是 Origin,表示請求來自哪個源。
除了 Origin 字段,“預檢請求”的頭信息包括兩個特殊字段。
? Access-Control-Request-Method:必須字段,列出瀏覽器的 CORS 請求會用到哪些 HTTP 方法;
? Access-Control-Request-Headers:這個字段是一個逗號 , 分隔的字符串,指定瀏覽器 CORS 請求會額外發送的頭信息字段,上面示例是 X-Custom-Header。

代碼實現

CORS(Cross-Origin Resource Sharing,跨域資源共享)通過在響應頭里加上一組特殊字段來告訴瀏覽器,這個資源允許被某些源訪問。

服務器端Cors的關鍵配置

struct CorsConfig 
{std::vector<std::string> allowedOrigins;//允許哪些域名可以訪問std::vector<std::string> allowedMethods; //允許哪些方法可以跨域調用std::vector<std::string> allowedHeaders; //允許前端請求里帶哪些請求頭bool allowCredentials = false; //不允許攜帶Cookie/Authorization header/TLS client cert 這類憑證信息int maxAge = 3600;             //瀏覽器緩存預檢請求的最大時長, 1 小時內同樣的跨域請求只會發送一次 OPTIONS,之后直接用緩存的結果static CorsConfig defaultConfig() {CorsConfig config;config.allowedOrigins = {"*"}; //這里允許的是所有域名config.allowedMethods = {"GET", "POST", "PUT", "DELETE", "OPTIONS"}; //在預檢請求(OPTIONS)的響應里告訴瀏覽器:后端接受哪些方法config.allowedHeaders = {"Content-Type", "Authorization"}; //允許前端帶Content-Type(比如 application/json)和Authorization(攜帶JWT Token等)return config;}
};

服務端解析預檢請求

處理客戶端發來的請求的流程如下:

  1. 判斷是否是預檢請求,如果是,進入下一步;否則不做處理(正常的請求,繼續后續的處理流程,響應)
  2. 檢查當前請求的源是否被允許,如果允許當前請求源則在響應頭中添加該源字段,狀態碼為204 No content,響應體為空,進入下一步
  3. 直接拋出特殊的響應對象(中斷后續的處理流程)

總結:如果是預檢請求,設置Cors的相關字段,直接返回;否則就進入正常的處理流程。

/***  @brief 請求前鉤子,所有請求進來時都會先執行* 如果是跨域的 OPTIONS 預檢請求,直接構造響應并拋出,跳過后續中間件/路由邏輯。*/
void CorsMiddleware::before(HttpRequest& request) 
{LOG_DEBUG << "CorsMiddleware::before - Processing request";// 如果是瀏覽器發起的預檢請求(CORS Preflight)if (request.method() == HttpRequest::Method::kOptions) {LOG_INFO << "Processing CORS preflight request";HttpResponse response;  // 創建預檢響應handlePreflightRequest(request, response);// 直接中斷后續處理流程,拋出特殊的響應對象throw response;}
}/*** @brief 處理 CORS 預檢請求(OPTIONS)* 會校驗 Origin,并返回允許的跨域頭*/
void CorsMiddleware::handlePreflightRequest(const HttpRequest& request, HttpResponse& response) 
{   // 從請求頭獲取 Originconst std::string& origin = request.getHeader("Origin");// 校驗是否允許跨域if (!isOriginAllowed(origin)) {LOG_WARN << "Origin not allowed: " << origin;response.setStatusCode(HttpResponse::k403Forbidden);return;}// 添加允許的跨域頭,對預檢請求返回 204 No Content;//即響應體為空,對應返回的是options字段的預檢請求的響應addCorsHeaders(response, origin);response.setStatusCode(HttpResponse::k204NoContent);LOG_INFO << "Preflight request processed successfully";
}/*** @brief 檢查給定 Origin 是否在允許列表里* @param origin 來自瀏覽器請求頭的 Origin* @return true 如果允許跨域,否則 false*/
bool CorsMiddleware::isOriginAllowed(const std::string& origin) const 
{return config_.allowedOrigins.empty() || std::find(config_.allowedOrigins.begin(), config_.allowedOrigins.end(), "*") != config_.allowedOrigins.end() ||std::find(config_.allowedOrigins.begin(), config_.allowedOrigins.end(), origin) != config_.allowedOrigins.end();}/*** @brief 給響應添加標準的 CORS 頭信息* @param response 當前響應對象* @param origin 本次請求允許的 Origin*/
void CorsMiddleware::addCorsHeaders(HttpResponse& response, const std::string& origin) 
{try {   // 設置允許的 Originresponse.addHeader("Access-Control-Allow-Origin", origin);// 是否允許攜帶 cookieif (config_.allowCredentials) {response.addHeader("Access-Control-Allow-Credentials", "true");}// 設置允許的方法列表,以,分割if (!config_.allowedMethods.empty()) {response.addHeader("Access-Control-Allow-Methods", join(config_.allowedMethods, ", "));}// 設置允許的自定義請求頭列表if (!config_.allowedHeaders.empty()) {response.addHeader("Access-Control-Allow-Headers", join(config_.allowedHeaders, ", "));}// 設置預檢結果的緩存時間(單位:秒)response.addHeader("Access-Control-Max-Age", std::to_string(config_.maxAge));LOG_DEBUG << "CORS headers added successfully";} catch (const std::exception& e) {LOG_ERROR << "Error adding CORS headers: " << e.what();}
}
/*** @brief 工具函數:把字符串數組用指定分隔符拼接起來* @param strings 字符串列表* @param delimiter 分隔符,如 ", "* @return 拼接后的字符串*/
std::string CorsMiddleware::join(const std::vector<std::string>& strings, const std::string& delimiter) 
{std::ostringstream result;for (size_t i = 0; i < strings.size(); ++i) {if (i > 0) result << delimiter;result << strings[i];}return result.str();
}

服務端填充響應

這里的響應指的是正常處理客戶端發來的請求后,在最終的響應頭中添加CORS的相關信息

/*** @brief 請求后鉤子,正常請求處理完畢后執行。* 不管是否跨域,都會在最終響應頭里加上 CORS 相關頭信息。*/
void CorsMiddleware::after(HttpResponse& response) 
{LOG_DEBUG << "CorsMiddleware::after - Processing response";// 直接添加CORS頭,簡化處理邏輯if (!config_.allowedOrigins.empty()) {// 如果允許所有源if (std::find(config_.allowedOrigins.begin(), config_.allowedOrigins.end(), "*") != config_.allowedOrigins.end()) {addCorsHeaders(response, "*");} else {// 簡單處理:只取第一個允許的來源(可以按需改成匹配實際請求來源)addCorsHeaders(response, config_.allowedOrigins[0]);}}
}

抓包分析

在這里插入圖片描述
在這里插入圖片描述
上圖展示了請求與響應的抓包分析數據:當客戶端向服務器請求加載登錄頁面時,服務器不僅會在響應體中返回HTML文件,還會在響應頭中附帶CORS配置信息供瀏覽器解析。
CORS 詳解,終于不用擔心跨域問題了

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/87482.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/87482.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/87482.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

FastAPI開發教程

FastAPI 是一個現代、高性能的 Python Web 框架&#xff0c;專為構建 APIs 設計。它基于 Python 類型提示&#xff0c;支持異步編程&#xff0c;并提供自動生成的交互式文檔&#xff08;Swagger UI 和 ReDoc&#xff09;。以下是 FastAPI 開發的核心指南&#xff1a; 1. 安裝 …

基于Spring Boot + MyBatis-Plus + Thymeleaf的評論管理系統深度解析

你好呀&#xff0c;我是小鄒。 個人博客系統日漸完善&#xff0c;現在的文章評論以及留言數量逐漸增多&#xff0c;所以今天重構了管理后臺的評論列表&#xff08;全量查詢 -> 分頁條件搜索&#xff09;。 示例圖 網頁端手機端一、系統架構設計與技術選型 系統采用前后端分離…

sqlmap學習筆記ing(1.Easy_SQLi(時間,表單注入))

題解 根據題目提示&#xff0c;應為SQL注入&#xff0c;題目頁面只有一個表單&#xff0c;用sqlmap進行表單注入。 使用--forms參數進行自動化表單注入&#xff0c;逐步得到flag。 ### 總結參數作用&#xff1a; -u 指定目標URL。 -C 指定列名&#xff08;多個…

SciPy 安裝使用教程

一、SciPy 簡介 SciPy&#xff08;Scientific Python&#xff09;是基于 NumPy 的開源科學計算庫&#xff0c;提供了數值積分、優化、信號處理、線性代數、統計分析等高級科學計算功能。它是構建 Python 科學計算生態系統的核心組件之一&#xff0c;常用于科研、工程、數據分析…

【AI大模型】通義大模型與現有企業系統集成實戰《CRM案例分析與安全最佳實踐》

簡介&#xff1a; 本文檔詳細介紹了基于通義大模型的CRM系統集成架構設計與優化實踐。涵蓋混合部署架構演進&#xff08;新增向量緩存、雙通道同步&#xff09;、性能基準測試對比、客戶意圖分析模塊、商機預測系統等核心功能實現。同時&#xff0c;深入探討了安全防護體系、三…

如何進行需求全周期管理

實現高效的需求全周期管理&#xff0c;應從以下五個方面入手&#xff1a;1、建立系統化需求來源渠道、2、設置清晰的評審與優先級策略、3、加強執行過程的協同與跟蹤、4、閉環需求驗收與上線反饋、5、構建長期的需求知識沉淀機制。 其中&#xff0c;“加強執行過程的協同與跟蹤…

熱傳導方程能量分析與邊界條件研究

題目 問題 10. (a) 考慮熱傳導方程在 J = ( ? ∞ , ∞ ) J = (-\infty, \infty) J=(?∞,∞) 上,證明“能量” E ( t ) = ∫ J u 2 ( x , t ) d x E(t) = \int_{J} u^{2}(x,t) dx E(t)=∫J?u2(x,t)dx (8) 不增加;進一步證明,除非 u ( x , t ) = 常數 u(x,t) = \text{常…

【AI News | 20250702】每日AI進展

AI Repos 1、LLM-RL-Visualized 提供100余張原創架構圖&#xff0c;全面涵蓋了 LLM (大語言模型)、VLM (視覺語言模型) 等大模型技術。內容深度解析了訓練算法&#xff08;如 RL、RLHF、GRPO、DPO、SFT、CoT 蒸餾等&#xff09;、效果優化策略&#xff08;如 RAG、CoT&#xf…

安徽省企業如何做信創產品認證?信創認證流程與費用詳解

安徽省作為長三角一體化發展的重要成員&#xff0c;正大力推進信息技術應用創新&#xff08;信創&#xff09;產業發展。依托合肥“中國聲谷”、蕪湖機器人及智能裝備基地等產業集群&#xff0c;以及省內對信創產業的政策扶持&#xff0c;企業通過信創認證后&#xff0c;能更好…

百度文心 ERNIE 4.5 開源:開啟中國多模態大模型開源新時代

百度文心 ERNIE 4.5 開源&#xff1a;開啟中國多模態大模型開源新時代 隨著DeepSeek-R1的橫空出示&#xff0c;越來越多大公司開始開源模型&#xff0c;像DeepSeek R1發布的時候Kimi同步開源了技術文檔&#xff0c;隨著R1推動著思維鏈推理技術的發展&#xff0c;開源社區也出現…

22、企業項目管理(Project)全體系構建:從基礎框架到智能防呆的完整解決方案

項目管理能力——企業VUCA戰略落地的核心樞紐 在VUCA&#xff08;烏卡時代&#xff0c;即VUCA時代&#xff0c;是指人們生活在一個不穩定性、不確定性、復雜性、模糊性的時代、境況或者世界中。vuca是volatility&#xff08;易變性VUCA&#xff09;&#xff0c;uncertainty&am…

分布式定時任務:Elastic-Job-Lite

Elastic-Job-Lite 是一款由 Apache 開源的輕量級分布式任務調度框架&#xff0c;屬于 ShardingSphere 生態體系的一部分。它專注于分布式任務調度&#xff0c;支持彈性伸縮、分片處理、高可用等特性&#xff0c;且不依賴中心化架構。 一、基礎 &#xff08;一&#xff09;核心特…

記錄一次生產環境ActiveMQ無法啟動的問題

這次遇到一個問題&#xff0c;是ActiveMQ無法啟動的&#xff0c;跟以往的現象不一樣。這次是在服務器重啟后出異常。 1、啟動ActiveMQ時提示&#xff1a;activemq/data/kahadb/db.data&#xff08;輸入輸出錯誤&#xff09;&#xff0c;NotFoundFileException異常 2、想著不應該…

大型語言模型幻覺檢測相關綜述

背景 1.1 幻覺檢測的定義與范圍 大型語言模型&#xff08;LLMs&#xff09;中的幻覺檢測 是指系統性地識別由LLMs生成的事實錯誤或無意義輸出的任務&#xff0c;而無需依賴外部證據 [Li et al., 2024; Zhang et al., 2024]。這項任務對于確保LLM生成內容的可靠性和可信度至關…

Python爬蟲與數據可視化教程

對于經常寫爬蟲的技術來說了&#xff0c;可視化大大的提高工作效率&#xff0c;可以讓獲取的數據更直觀的展示在面前&#xff0c;下面我將通過具體實操給大家展示下多種可視化具體教程&#xff0c;希望能都幫助大家。 下面是一個完整的Python爬蟲和數據可視化解決方案&#xff…

【GHS】Green Hills軟件MULTI-IDE的安裝教程

前言&#xff1a;MULTI-IDE作為一款Green Hills開發的支持C/C、Ada等語言的嵌入式開發環境&#xff0c;由于其優異的性能&#xff0c;所以在汽車電子軟件的開發中占有重要地位。但是這款IDE需要付費使用&#xff0c;對于個人學習而言不太友好&#xff0c;所以這里介紹一款PJ版本…

Web攻防-文件上傳黑白名單MIMEJS前端執行權限編碼解析OSS存儲分域名應用場景

知識點&#xff1a; 1、WEB攻防-文件上傳-前端&黑白名單&MIME&文件頭等 2、WEB攻防-文件上傳-執行權限&解碼還原&云存儲&分站等 3、WEB攻防-文件上傳-JS提取&特定漏洞&第三方編輯器 4、WEB攻防-文件上傳-思維導圖形成 常規文件上傳&#xff1a…

Odoo系統大型業務優化實戰

目錄 背景說明ORM與模型優化數據量處理策略接口與報表優化系統架構優化監控與診斷工具項目實戰總結&#xff08;案例&#xff09;后續優化建議性能優化檢查清單總結 一、背景說明 在 Odoo 項目中&#xff0c;隨著業務不斷擴展&#xff0c;系統常常面臨如下挑戰&#xff1a; …

【2.4 漫畫SpringBoot實戰】

?? 漫畫SpringBoot實戰 ?? 學習目標:掌握SpringBoot企業級開發,從零到一構建現代化Java應用 ?? 目錄 SpringBoot核心特性自動配置原理Web開發實戰數據訪問與事務監控與部署?? 漫畫引言 小明: “為什么SpringBoot這么受歡迎?” 架構師老王: “SpringBoot就像全自動…

美國站群服務器的優勢和應用與選擇指南

在當今數字化時代&#xff0c;互聯網業務的蓬勃發展促使各類企業和個人不斷尋求高效、穩定且功能強大的網絡解決方案。美國站群服務器作為一種備受矚目的網絡基礎設施&#xff0c;正逐漸成為眾多從事跨境電商、搜索引擎優化&#xff08;SEO&#xff09;、內容分發、數據采集等業…