Flask服务器CORS报错排查:已配置跨域仍无法前端请求
问题背景
搭建Flask服务器提供/api/data接口,POSTMAN请求正常,但前端调用时触发CORS错误:
Access to fetch at 'server/api/data' from origin 'website' has been blocked by CORS policy: 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.
已通过CORS(app)配置跨域,并在路由中手动添加响应头,服务器部署于Vercel,此前运行正常,现突然失效。
相关代码:
@app.route('/api/data', methods=['GET', 'OPTIONS']) def get_data(): if request.method == 'OPTIONS': response = jsonify() else: articles = db.articles.find({}, {"_id": 0}) articles_list = list(articles) response = jsonify(articles_list) response.headers.add('Access-Control-Allow-Origin', 'website link') response.headers.add('Access-Control-Allow-Headers', 'Content-Type') response.headers.add('Access-Control-Allow-Methods', 'GET') return response
app = Flask(__name__) CORS(app)
核心问题与修复方案
1. 手动响应头与flask-cors冲突
flask-cors插件会自动处理OPTIONS预检请求并添加标准CORS响应头,手动添加的头可能覆盖或干扰插件的正常输出,导致Access-Control-Allow-Origin未正确设置。
修复:移除路由内手动添加的CORS响应头,由flask-cors统一处理
修改后的代码:
from flask import Flask, jsonify, request from flask_cors import CORS app = Flask(__name__) # 明确指定允许的前端域名,替换为你的实际地址 CORS(app, origins=["https://your-frontend-domain.com"]) # 无需手动处理OPTIONS请求,flask-cors会自动处理 @app.route('/api/data', methods=['GET']) def get_data(): articles = db.articles.find({}, {"_id": 0}) articles_list = list(articles) return jsonify(articles_list)
2. Vercel部署层面的CORS配置缺失
Vercel的部署环境可能会覆盖或忽略Flask应用内的CORS配置,尤其是当存在缓存或部署配置变更时。
修复:添加vercel.json配置CORS规则
在项目根目录创建vercel.json文件,内容如下:
{ "headers": [ { "source": "/api/(.*)", "headers": [ { "key": "Access-Control-Allow-Origin", "value": "https://your-frontend-domain.com" }, { "key": "Access-Control-Allow-Methods", "value": "GET, OPTIONS" }, { "key": "Access-Control-Allow-Headers", "value": "Content-Type" } ] } ] }
添加后重新部署Vercel项目,确保配置生效。
3. 缓存或部署状态异常
Vercel的缓存机制可能导致旧配置残留,尝试以下操作:
- 在Vercel控制台手动触发重新部署,勾选"清除构建缓存"选项
- 检查前端请求的服务器地址是否正确,避免使用缓存的旧域名
内容的提问来源于stack exchange,提问作者D3M0N

