Python中的跨域資源共享(CORS)處理

在這里插入圖片描述

在Web開發中,跨域資源共享(CORS)是瀏覽器強制執行的安全機制,用于控制不同源(協議+域名+端口)之間的資源交互。下面我將通過Python示例詳細講解CORS的實現。

原生Python實現CORS

Flask框架手動實現CORS

from flask import Flask, jsonify, request, make_responseapp = Flask(__name__)# 手動實現CORS中間件
@app.after_request
def add_cors_headers(response):# 設置允許的來源(實際項目中應使用白名單)response.headers['Access-Control-Allow-Origin'] = 'http://localhost:3000'# 允許的請求方法response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'# 允許的請求頭response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'# 是否允許攜帶憑證(如cookies)response.headers['Access-Control-Allow-Credentials'] = 'true'# 預檢請求緩存時間(秒)response.headers['Access-Control-Max-Age'] = '86400'return response# 處理預檢請求
@app.route('/api/data', methods=['OPTIONS'])
def handle_preflight():response = make_response()response.headers.add("Access-Control-Allow-Origin", "http://localhost:3000")response.headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization")response.headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")response.headers.add("Access-Control-Allow-Credentials", "true")return response# API端點示例
@app.route('/api/data', methods=['GET', 'POST'])
def api_data():if request.method == 'GET':return jsonify({"message": "GET請求成功", "data": [1, 2, 3]})elif request.method == 'POST':data = request.jsonreturn jsonify({"message": "POST請求成功", "received_data": data})if __name__ == '__main__':app.run(port=5000, debug=True)

使用Flask-CORS擴展

from flask import Flask, jsonify, request
from flask_cors import CORSapp = Flask(__name__)# 配置CORS
cors = CORS(app, resources={r"/api/*": {"origins": "http://localhost:3000"}},supports_credentials=True)# 或者更細粒度的控制
# cors = CORS()
# cors.init_app(app, resources={r"/api/*": {"origins": ["http://localhost:3000"]}})# API端點
@app.route('/api/users', methods=['GET'])
def get_users():return jsonify([{"id": 1, "name": "張三", "email": "zhangsan@example.com"},{"id": 2, "name": "李四", "email": "lisi@example.com"}])@app.route('/api/users', methods=['POST'])
def create_user():data = request.json# 在實際應用中,這里會將數據保存到數據庫return jsonify({"message": "用戶創建成功","user": data,"id": 3}), 201if __name__ == '__main__':app.run(port=5000, debug=True)

FastAPI框架實現CORS

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddlewareapp = FastAPI()# 配置CORS中間件
app.add_middleware(CORSMiddleware,allow_origins=["http://localhost:3000"],  # 允許的來源列表allow_credentials=True,  # 允許攜帶憑證allow_methods=["*"],      # 允許所有方法allow_headers=["*"],      # 允許所有頭部expose_headers=["X-Custom-Header"],  # 暴露自定義頭部max_age=86400,            # 預檢請求緩存時間(秒)
)# API端點
@app.get("/api/products")
def get_products():return [{"id": 1, "name": "筆記本電腦", "price": 5999},{"id": 2, "name": "智能手機", "price": 3999},{"id": 3, "name": "平板電腦", "price": 2999}]@app.post("/api/products")
def create_product(product: dict):# 在實際應用中,這里會處理產品創建邏輯return {"message": "產品創建成功","product": product,"id": 4}if __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=8000)

前端示例(使用fetch API)

<!DOCTYPE html>
<html>
<head><title>CORS測試前端</title><style>body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;max-width: 800px;margin: 0 auto;padding: 20px;background-color: #f5f7fa;color: #333;}.container {background: white;padding: 25px;border-radius: 10px;box-shadow: 0 4px 15px rgba(0,0,0,0.1);}h1 {color: #2c3e50;text-align: center;}.section {margin-bottom: 30px;padding: 20px;border-radius: 8px;background: #f8f9fa;}button {background: #3498db;color: white;border: none;padding: 10px 15px;border-radius: 4px;cursor: pointer;font-size: 16px;transition: background 0.3s;}button:hover {background: #2980b9;}.result {margin-top: 15px;padding: 15px;background: #e8f4fd;border-radius: 5px;min-height: 50px;font-family: monospace;white-space: pre-wrap;}.error {background: #fde8e8;color: #e74c3c;}</style>
</head>
<body><div class="container"><h1>CORS測試前端</h1><div class="section"><h2>GET請求測試</h2><button onclick="testGetRequest()">測試GET請求</button><div id="getResult" class="result"></div></div><div class="section"><h2>POST請求測試</h2><button onclick="testPostRequest()">測試POST請求</button><div id="postResult" class="result"></div></div><div class="section"><h2>帶憑證的請求</h2><button onclick="testRequestWithCredentials()">測試帶憑證的請求</button><div id="credentialsResult" class="result"></div></div></div><script>const apiBaseUrl = 'http://localhost:5000/api';function displayResult(elementId, data, isError = false) {const resultElement = document.getElementById(elementId);resultElement.textContent = JSON.stringify(data, null, 2);resultElement.className = isError ? 'result error' : 'result';}// 測試GET請求async function testGetRequest() {try {const response = await fetch(`${apiBaseUrl}/data`);if (!response.ok) throw new Error(`HTTP錯誤! 狀態: ${response.status}`);const data = await response.json();displayResult('getResult', data);} catch (error) {displayResult('getResult', { error: error.message }, true);}}// 測試POST請求async function testPostRequest() {try {const response = await fetch(`${apiBaseUrl}/data`, {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ name: '測試數據', value: 42 })});if (!response.ok) throw new Error(`HTTP錯誤! 狀態: ${response.status}`);const data = await response.json();displayResult('postResult', data);} catch (error) {displayResult('postResult', { error: error.message }, true);}}// 測試帶憑證的請求async function testRequestWithCredentials() {try {const response = await fetch(`${apiBaseUrl}/data`, {method: 'GET',credentials: 'include'  // 包含憑據(如cookies)});if (!response.ok) throw new Error(`HTTP錯誤! 狀態: ${response.status}`);// 檢查響應頭中是否有自定義頭const customHeader = response.headers.get('X-Custom-Header');const data = await response.json();if (customHeader) {data.credentials = `檢測到憑證請求! 自定義頭: ${customHeader}`;}displayResult('credentialsResult', data);} catch (error) {displayResult('credentialsResult', { error: error.message,note: "請確保服務器設置了 'Access-Control-Allow-Credentials: true' 并且 'Access-Control-Allow-Origin' 不是 '*'"}, true);}}</script>
</body>
</html>

CORS關鍵概念總結

概念Python實現方式說明
Access-Control-Allow-Originresponse.headers['Access-Control-Allow-Origin'] = 'http://example.com'指定允許訪問資源的來源
Access-Control-Allow-Methodsresponse.headers['Access-Control-Allow-Methods'] = 'GET, POST'允許的HTTP方法
Access-Control-Allow-Headersresponse.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'允許的請求頭
Access-Control-Allow-Credentialsresponse.headers['Access-Control-Allow-Credentials'] = 'true'是否允許攜帶憑證
Access-Control-Max-Ageresponse.headers['Access-Control-Max-Age'] = '86400'預檢請求緩存時間
預檢請求處理實現OPTIONS方法處理處理瀏覽器發送的OPTIONS預檢請求
第三方庫支持Flask-CORS, FastAPI CORSMiddleware簡化CORS配置的庫

常見問題解決

  1. CORS錯誤:No ‘Access-Control-Allow-Origin’ header

    • 確保服務器正確設置了Access-Control-Allow-Origin響應頭
    • 檢查請求來源是否在允許的源列表中
  2. 預檢請求失敗

    • 確保服務器正確處理OPTIONS請求
    • 檢查Access-Control-Allow-MethodsAccess-Control-Allow-Headers是否包含請求中使用的方法和頭
  3. 帶憑證請求失敗

    • 服務器需設置Access-Control-Allow-Credentials: true
    • Access-Control-Allow-Origin不能是通配符*,必須指定具體域名
    • 前端請求需設置credentials: 'include'
  4. 復雜請求被阻止

    • 對于PUT、DELETE或自定義頭的請求,確保服務器響應預檢請求

最佳實踐

  1. 使用白名單:不要使用*作為允許的源,而是維護一個允許的域名列表
  2. 限制方法:只允許必要的HTTP方法(GET, POST等)
  3. 限制頭:只允許必要的請求頭
  4. 使用中間件/庫:使用Flask-CORS或FastAPI的CORSMiddleware簡化實現
  5. 環境區分:開發環境可放寬CORS設置,生產環境應嚴格限制
  6. 監控與日志:記錄被拒絕的跨域請求以識別潛在問題

通過正確配置CORS,可以安全地實現跨域請求,同時保護用戶數據安全。

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

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

相關文章

Kruskal算法剖析與py/cpp/Java語言實現

Kruskal算法剖析與py/cpp/Java語言實現 一、Kruskal算法的基本概念1.1 最小生成樹1.2 Kruskal算法核心思想 二、Kruskal算法的執行流程三、Kruskal算法的代碼實現3.1 Python實現3.2 C實現3.3 Java實現 四、算法復雜度分析4.1 時間復雜度4.2 空間復雜度 五、Kruskal算法應用場景…

微信小程序返回上一頁監聽

本文實現的是微信小程序在返回上一頁時獲取通知并自定義業務。 最簡單的實現&#xff1a; 使用 wx.enableAlertBeforeUnload() 優點&#xff1a;快速接入 缺點&#xff1a;手勢不能識別、無法自定義彈窗內容&#xff08;僅詢問&#xff09; 方法二&#xff1a; page-conta…

Excel 統計某個字符串在指定區域出現的次數

【本文概要】 Excel 統計某個字符串在指定區域出現的次數&#xff1a; 1、Excel 統計一個單元格內的某字符串的出現次數 2、Excel 統計某一列所有單元格內的某字符串的出現次數 3、Excel 統計某一區域所有單元格內的某字符串的出現次數 1、Excel 統計一個單元格內的某字符串的出…

生物化學:藥品藥物 營養和補充劑信息 第三方認證信息 常見誤區 匯總

常見維生素和礦物質成分表 成分名稱好處副作用&#xff08;超量或敏感情況&#xff09;運作方式推薦日劑量&#xff08;成人&#xff09;劑量說明維生素A&#xff08;視黃醇&#xff09;視力、免疫、皮膚健康過量可致肝損傷、頭痛、脫發調節視網膜功能、細胞分化700–900 g RA…

mock庫知識筆記(持續更新)

文章目錄 mock簡介導入方式參數簡介使用場景&#xff08;待更新&#xff09;常見問題總結&#xff08;待更新&#xff09;Python代碼官網 mock簡介 mock是一個模擬對象庫&#xff0c;具有模擬其他python對象的功能&#xff0c;還能指定模擬對象的返回值和設置模擬對象的屬性。…

扇形 圓形 面積公式

? 一、圓的面積公式 全圓面積&#xff1a; A circle π r 2 A_{\text{circle}} \pi r^2 Acircle?πr2 ? 二、扇形的面積公式&#xff08;兩種制式&#xff09; 弧度制&#xff1a; A sector 1 2 r 2 θ A_{\text{sector}} \frac{1}{2} r^2 \theta Asector?21?r2θ …

怎樣將win11+ubuntu雙系統的ubuntu從機械硬盤遷移至固態硬盤(1)

將 Ubuntu 從機械硬盤遷移到固態硬盤是一個涉及多個步驟的過程。以下是一個基本的遷移指南&#xff1a; 1. 前期準備 1.1 備份數據&#xff1a; 確保你已備份數據&#xff0c;以防止在遷移過程中出現意外導致任何數據丟失。 1.2 固態硬盤安裝&#xff1a; 確保固態硬盤正確…

js中common.js和ECMAScript.js區別

以下是關于 CommonJS 和 ECMAScript Modules&#xff08;ESM&#xff09;的詳細對比分析&#xff0c;包含底層原理和示例說明&#xff1a; &#x1f9e9; 核心差異對比表 特性CommonJSES Modules來源Node.js 社區規范ECMAScript 語言標準加載方式動態加載&#xff08;運行時解…

玻纖效應的時序偏差

隨著比特率繼續飆升&#xff0c;光纖編織效應時序偏移正成為一個越來越嚴重的問題。對于 5GB/s 及以上的信號傳輸速率&#xff0c;它實際上會毀了您的一天。例如&#xff0c;左圖顯示由于 12.7 英寸的纖維編織效果&#xff0c;5GB/s 的接收眼完全閉合。使用 Agilent ADS 軟件進…

異步上傳石墨文件進度條前端展示記錄(采用Redis中String數據結構實現)

事件起因是客戶現場需要從石墨文檔中獲取文件信息&#xff0c;文件信息存在存在多個&#xff0c;進行批量上傳。為了用戶的友好型體驗&#xff0c;需要做進行條展示的方式&#xff0c;具體實現見下文… 上傳流程介紹 石墨文檔支持從鏈接&#x1f517;方式獲取文件信息&#xf…

3D建模的全景圖譜:從55個工具到元宇宙的數字革命

3D建模已從專業工程師的工具箱演變為全民創作的數字語言。從代碼驅動的精確建模到AI自動生成紋理&#xff0c;從開源協作到程序化生成城市&#xff0c;技術正重塑我們創造虛擬世界的方式。本文將系統解析55個核心3D建模工具/插件&#xff0c;涵蓋在線編輯器、開源軟件、程序化生…

jsrpc進階模式 秒殺js前端逆向問題 burp聯動進行爆破

案例演示 思路就是 這個 jsrpc遠程加載加密函數的方法就是 在js代碼中進行插入一個 遠程加載的代碼 從而實現 &#xff1a; 第一步還是使用 js_tools 進行 查找算法的位置 這個可以幫助我們找到明文>密文 加密算法函數的位置 因為這個需要我們進行js前端代碼的修改 所以…

基于BERT-Prompt的領域句子向量訓練方法

基于BERT-Prompt的領域句子向量訓練方法 一、核心原理:基于BERT-Prompt的領域句子向量訓練方法 論文提出一種結合提示學習(Prompt Learning)和BERT的領域句子向量訓練方法,旨在解決裝備保障領域文本的語義表示問題。核心原理如下: 以下通過具體例子解釋傳統詞向量方法和…

Python PyMySQL

1.PyMySQL是什么 是Python操作mysql的一個包 2.PyMySQL使用基本步驟 2.1 創建連接 conn pymysql.connect(host10.248.53.148,password123456,port3306,userroot,databasetest_database,charsetutf8)2.2 游標 2.2.1 什么是游標 游標實際上是一種能從包括多條數據記錄的結果…

OC—UI學習-1

OC—UI學習 UILabel UILabel是UIKit框架中的一個類Label主要參數 text&#xff1a;文本frame&#xff1a;位置框架backgroundcolor&#xff1a;背景顏色textAlignment&#xff1a;設置文本在Label中的位置textColor&#xff1a;文本顏色shadowColor&#xff1a;陰影顏色shado…

【應用密碼學】實驗七 Hash函數——SM3

一、實驗要求與目的 理解哈希函數的基本原理及在密碼學中的應用&#xff1b;掌握國密哈希標準 SM3 的算法結構&#xff1b;編程實現 SM3 摘要算法&#xff0c;包括消息填充、消息擴展、壓縮函數及摘要輸出&#xff1b;對中間變量 W、W′ 和 A~H 的迭代過程進行可視化&#xff…

進行性核上性麻痹護理之道:助力患者舒適生活

進行性核上性麻痹是一種緩慢進展的神經退行性疾病&#xff0c;主要影響患者的運動、語言和吞咽功能&#xff0c;給日常生活帶來諸多不便。除了遵醫囑接受藥物或物理治療&#xff0c;科學的健康護理對延緩病情發展、提升生活質量尤為重要。 運動康復是護理的關鍵環節。由于患者常…

5G 核心網中 NRF 網元的功能、接口及參數詳解

引言 在 5G 核心網的架構體系里,網絡存儲功能(Network Repository Function,NRF)占據著關鍵地位,承擔著核心網網絡功能(Network Function,NF)的注冊、發現以及服務管理等重要任務,為整個 5G 網絡的高效穩定運行提供了堅實支撐。接下來,讓我們深入剖析 NRF 網元在注冊…

HUAWEI交換機配置鏡像口驗證(eNSP)

技術術語&#xff1a; 流量觀察口&#xff1a;就是我們常說的鏡像口&#xff0c;被觀察的流量的引流目的端口 流量源端口&#xff1a;企業生產端口&#xff0c;作為觀察口觀察對象。 命令介紹&#xff1a; [核心交換機]observe-port [觀察端口ID或編號&#xff08;數字&am…

Spring AI Alibaba 發布企業級 MCP 分布式部署方案

作者&#xff1a; 影子&#xff0c;劉宏宇&#xff0c;劉軍 Spring AI 通過集成 MCP 官方的 java sdk&#xff0c;讓 Spring Boot 開發者可以非常方便的開發自己的 MCP 服務&#xff0c;把自己企業內部的業務系統通過標準 MCP 形式發布為 AI Agent 能夠接入的工具&#xff1b;…