Flask配置CORS跨域失败求助:按文档设置仍报错
解决Flask API跨域问题的排查与修复方案
1. 确认Flask-Cors安装与版本
先确保安装的是官方包,且版本为最新:
pip install flask-cors pip install --upgrade flask-cors
避免使用名称类似的第三方包,确保依赖正确。
2. 验证基础配置的正确性
很多错误源于配置写法疏漏,以下是全局配置的正确示例:
from flask import Flask from flask_cors import CORS app = Flask(__name__) # 开发阶段允许所有来源,生产环境需指定具体域名 CORS(app, resources={r"/api/*": {"origins": "*"}}) # 生产环境示例:指定前端域名 # CORS(app, resources={r"/api/*": {"origins": "http://your-frontend-domain.com"}}) @app.route('/api/test') def test_api(): return {"status": "success", "data": "test content"} if __name__ == '__main__': app.run(debug=True)
若使用蓝图(Blueprint),需为蓝图单独配置CORS,或确保全局配置覆盖蓝图路由前缀。
3. 处理预检OPTIONS请求
浏览器会先发OPTIONS请求做预检,若自定义逻辑拦截了该请求,会导致跨域失败:
- 不要手动在路由中处理OPTIONS请求,让Flask-Cors自动处理
- 检查自定义的
before_request装饰器,确保放过OPTIONS请求:
若存在上述代码,需确保返回200状态码;若无必要,直接删除该逻辑,交由Flask-Cors处理。@app.before_request def before_req(): if request.method == 'OPTIONS': return '', 200
4. 配置自定义请求/响应头
如果前端请求带有自定义头(如Authorization、X-Requested-With),需在CORS配置中明确允许:
CORS(app, resources={r"/api/*": { "origins": "http://localhost:3000", "allow_headers": ["Content-Type", "Authorization"], "expose_headers": ["Content-Length"] }})
同时通过浏览器开发者工具的Network标签检查响应头,确认Access-Control-Allow-Origin字段存在,若不存在则说明CORS配置未生效。
5. 排查服务器环境问题
- 若使用Gunicorn、uWSGI等生产服务器,确保CORS配置在
app初始化时就完成加载,而非路由定义之后 - 若存在Nginx反向代理,需在Nginx配置中添加CORS头,避免与Flask端配置冲突:
这种情况下,可关闭Flask端的CORS配置,防止重复设置头导致异常。location /api { add_header Access-Control-Allow-Origin http://localhost:3000; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"; add_header Access-Control-Allow-Headers "Content-Type, Authorization"; if ($request_method = OPTIONS) { return 204; } proxy_pass http://127.0.0.1:5000; }
6. 测试简化场景定位问题
先搭建最简化的测试API,排除其他中间件或自定义逻辑的干扰:
from flask import Flask from flask_cors import CORS app = Flask(__name__) CORS(app) @app.route('/') def simple_test(): return {"message": "cross domain test success"} if __name__ == '__main__': app.run(debug=True)
用前端发送简单请求测试:
fetch('http://localhost:5000/') .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.error(err));
若简化版正常工作,再逐步添加原项目的代码(如蓝图、中间件),定位导致跨域失败的具体逻辑。
内容的提问来源于stack exchange,提问作者rumcajs
相关产品推荐
相关产品推荐

