设置Access-Control-Allow-Origin头时如何绕过跨域预检请求?
解决Flask跨域预检请求问题及正确配置CORS
咱们一步步拆解问题所在,然后搞定它:
先纠正前端AJAX的错误
你现在的AJAX代码里有个关键误区:Access-Control-Allow-Origin是后端返回给浏览器的响应头,不是前端请求里要加的头!把这个从请求的headers里删掉,而且发送JSON数据时,需要明确告诉后端数据格式是JSON,否则request.get_json()会拿不到数据。修改后的AJAX代码:
$.ajax({ url: "http://127.0.0.1:5000/", method: "POST", contentType: "application/json", // 声明请求体是JSON格式 data: JSON.stringify(dict), // 将JavaScript字典转为JSON字符串 success: function() { console.log("提交成功"); }, error: function(xhr) { console.error("请求失败:", xhr); } });
后端处理跨域的两种方案
方案1:使用Flask-CORS扩展(推荐)
这是最省心的方式,它会自动处理预检请求(OPTIONS),并帮你设置正确的CORS响应头。
- 先安装扩展:
pip install flask-cors
- 修改Flask代码,初始化CORS:
from flask import Flask, request from flask_cors import CORS app = Flask(__name__) # 只允许你的前端网站(127.0.0.1:8000)跨域访问,更安全 CORS(app, resources={r"/": {"origins": "http://127.0.0.1:8000"}}) @app.route('/', methods=['POST']) def hello_world(): ok = request.get_json() # 加个判断避免KeyError if ok and 'id' in ok: print(ok['id']) return '', 200 if __name__ == '__main__': app.run()
如果想允许所有源(开发环境可以临时用,生产环境不推荐),直接用CORS(app)即可。
方案2:手动处理预检请求和CORS头
如果不想用第三方扩展,可以手动处理OPTIONS预检请求,并在响应中添加正确的CORS头:
from flask import Flask, request, make_response app = Flask(__name__) @app.route('/', methods=['POST', 'OPTIONS']) def hello_world(): # 处理浏览器的预检OPTIONS请求 if request.method == 'OPTIONS': response = make_response() # 允许你的前端域名跨域 response.headers["Access-Control-Allow-Origin"] = "http://127.0.0.1:8000" # 允许请求携带Content-Type头(因为我们发送的是JSON) response.headers["Access-Control-Allow-Headers"] = "Content-Type" # 允许POST方法 response.headers["Access-Control-Allow-Methods"] = "POST" return response # 处理正常的POST请求 ok = request.get_json() if ok and 'id' in ok: print(ok['id']) # 响应时也要添加CORS头 response = make_response('', 200) response.headers["Access-Control-Allow-Origin"] = "http://127.0.0.1:8000" return response if __name__ == '__main__': app.run()
为什么会出现预检请求?
当你的请求满足以下任一条件时,浏览器会先发OPTIONS预检请求:
- 请求方法不是GET/HEAD/POST
- POST请求的Content-Type不是
application/x-www-form-urlencoded、multipart/form-data或text/plain(你这里用的是JSON,属于非简单类型) - 请求包含自定义头
所以必须让后端正确处理OPTIONS请求,浏览器才会继续发送真正的POST请求。
内容的提问来源于stack exchange,提问作者yellowbowlmigration
相关产品推荐
相关产品推荐

