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

设置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响应头。

  1. 先安装扩展:
pip install flask-cors
  1. 修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:10:41