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

已启用Flask CORS仍遇Axios POST跨域错误,求解决方案

Flask CORS启用后仍遇跨域错误排查

环境与代码

后端(Flask,5000端口)

from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/process", methods=['POST'])
def process():
    print('process')
    # process here
    return jsonify({'response': 'OK'})

前端(React,3001端口)

import axios from 'axios';
import FormData from 'form-data';

const sendFile = (binary: ArrayBuffer) => {
    console.log('sending file');
    const formData = new FormData();
    formData.append('image', new Blob([binary]), file.name);

    const options = {
        method: 'POST',
        url: 'http://localhost:5000/process',
        // url: 'https://postman-echo.com/post',
        data: formData,
    };
    axios(options)
        .then(response => {
            console.log(response);
        })
        .catch(error => {
            console.error(error);
        });
};

报错信息

Access to XMLHttpRequest at 'http://localhost:5000/process' from origin 'http://localhost:3001' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

POST http://localhost:5000/process net::ERR_FAILED 403 (Forbidden)

验证情况

  • VSCode REST Client测试请求正常(不遵循同源策略)
  • curl验证后端返回头包含Access-Control-Allow-Origin: *:
% curl -I -X POST http://localhost:5000/process
HTTP/1.1 200 OK
Server: Werkzeug/2.2.2 Python/3.10.8
Date: Fri, 01 Dec 2023 09:37:22 GMT
Content-Type: application/json
Content-Length: 23
Access-Control-Allow-Origin: *
Connection: close

问题解答

1. 已启用Flask CORS仍无效的解决方向

  • 显式为路由配置CORS:全局CORS配置可能被路由级别的逻辑覆盖,给目标路由添加@cross_origin()装饰器:
    from flask_cors import cross_origin
    
    @app.route("/process", methods=['POST'])
    @cross_origin()
    def process():
        print('process')
        return jsonify({'response': 'OK'})
    
  • 升级Flask-CORS版本:旧版本可能存在兼容问题,执行pip install --upgrade flask-cors更新
  • 检查反向代理/防火墙:如果后端在Nginx等代理后,需确保代理未移除Access-Control-Allow-Origin头
  • 查看浏览器实际响应头:在Chrome开发者工具「网络」面板中,查看POST/OPTIONS请求的真实响应头,确认CORS头是否存在——curl请求和浏览器请求的头信息差异可能导致后端返回不同结果

2. 前端请求与VSCode REST Client的差异及修正

两者核心差异在于**浏览器自动携带的头信息(如Origin)**和FormData的处理方式:

  • 前端无需引入Node.js的form-data库,浏览器原生支持FormData,引入第三方库会导致请求头格式异常
  • 修正后的前端代码:
    import axios from 'axios';
    
    const sendFile = (binary: ArrayBuffer, file: File) => { // 需传入file参数
        console.log('sending file');
        const formData = new FormData();
        formData.append('image', new Blob([binary]), file.name);
    
        axios.post('http://localhost:5000/process', formData)
            .then(response => console.log(response))
            .catch(error => console.error(error));
    };
    

3. curl显示有CORS头但浏览器报错的原因

  • curl请求不带Origin头,后端返回*允许所有源;但浏览器请求会携带Origin: http://localhost:3001,如果后端存在路由匹配错误、中间件拦截等问题,可能不会返回正确的CORS头
  • curl用-I发送的是HEAD请求,而浏览器发送的是POST请求,若后端POST路由处理逻辑异常(如FormData解析失败),可能返回403且未注入CORS头

4. 403错误与CORS的关系

这是同一个问题导致的两个关联报错:

  • 浏览器先校验CORS头,若未找到则直接拦截请求,同时显示403状态码(可能是浏览器阻断标记,或后端因请求格式错误返回403)
  • 若后端因前端请求格式错误返回403,Flask-CORS可能无法注入CORS头,导致浏览器同时抛出CORS和403错误

5. 关于简单请求的判断

你的请求不属于简单请求,会触发OPTIONS预检请求:

  • 简单请求需满足:请求方法为GET/HEAD/POST;Content-Type仅为application/x-www-form-urlencoded/multipart/form-data/text/plain;无自定义头
  • 虽然Content-Type是multipart/form-data,但携带文件的FormData请求会被浏览器判定为需要预检,必须确保后端能正确处理OPTIONS请求并返回CORS头

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:05:27