You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask配置Swagger UI遇跨域(CORS)问题,求解决方案

Flask+Swagger调用外部端点遇CORS问题的解决方案

问题描述

我在Python中用Flask配置了Swagger UI,Swagger里的多个端点需要调用非本地服务器,但每次调用都触发CORS错误:

Access to fetch at 'https://XXXXXXXXXXXXX.XX/' from origin 'https://XX.XX.XX.X:40' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

已尝试的方案:

  • 使用flask_cors库全局配置CORS
  • 自定义flask_cors的resources和allow_headers参数
  • 分别用HTTP/HTTPS启动Flask
  • 查阅大量资料但无效

目前只能通过关闭Chrome安全模式临时开发:chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security,且Postman可正常调用所有端点。


问题根源

CORS错误的核心不在你的Flask/Swagger服务,而在你要调用的外部目标服务器。浏览器的CORS策略要求跨域请求的响应必须携带Access-Control-Allow-Origin头,而你调用的外部服务器未返回该头,因此浏览器拦截了响应。Postman不受浏览器CORS规则限制,所以可以正常调用。


解决方案

方案1:Flask反向代理(推荐无外部服务器权限场景)

通过Flask做一层代理,让Swagger的请求先发给同域的Flask服务,再由Flask转发到外部端点。这样浏览器只和同域服务交互,不会触发CORS检查。

示例代码:

from flask import Flask, request
import requests
from flask_cors import CORS
from flask_restx import Api  # 适配flask-restx的Swagger配置

app = Flask(__name__)
api = Api(app)
CORS(app)

# 代理外部服务的通用路由
@app.route('/proxy/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'])
def proxy_request(path):
    # 替换为实际的外部服务器基础URL
    external_base_url = "https://XXXXXXXXXXXXX.XX/"
    target_url = f"{external_base_url}{path}"

    # 转发请求头(排除Host避免冲突)
    forward_headers = {k: v for k, v in request.headers.items() if k.lower() != 'host'}
    
    # 发送请求到外部服务器
    response = requests.request(
        method=request.method,
        url=target_url,
        headers=forward_headers,
        data=request.get_data(),
        params=request.args,
        allow_redirects=True
    )

    # 处理响应头,排除浏览器不允许跨域设置的头
    excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
    response_headers = [
        (k, v) for k, v in response.raw.headers.items()
        if k.lower() not in excluded_headers
    ]

    return (response.content, response.status_code, response_headers)

# 原有的Swagger API配置...
if __name__ == '__main__':
    # 若用HTTPS,可使用adhoc临时证书或自有证书
    app.run(ssl_context='adhoc', port=40)

修改Swagger端点地址:将原来的https://XXXXXXXXXXXXX.XX/xxx改为/proxy/xxx,让请求先经过Flask代理。

方案2:修改外部服务器CORS配置(适用于有权限修改外部服务场景)

如果你能控制外部服务器,需要:

  1. 在外部服务器的响应中添加Access-Control-Allow-Origin头,值为你的Swagger服务Origin(即https://XX.XX.XX.X:40),生产环境不建议用*
  2. 确保外部服务器正确处理OPTIONS预请求,返回Access-Control-Allow-Methods、Access-Control-Allow-Headers等必要头

方案3:开发环境临时方案

除了你当前使用的Chrome不安全模式,还可以:

  • 使用CORS浏览器插件(如CORS Unblock)临时绕过检查,仅用于开发
  • 使用curl或Python脚本测试接口,避开浏览器CORS限制

内容的提问来源于stack exchange,提问作者Ankit Bijlwan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 05:45:38