React+Axios对接Flask后端出现CORS错误的排查求助
问题描述
React前端+Flask后端的应用,从fetch切换为Axios后,持续抛出CORS错误:
Access to XMLHttpRequest at 'http://127.0.0.1:5050/api/user/register' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
前端Axios代码:
const config = { headers: { "Access-Control-Allow-Origin": "*", "Content-Type": "application/json" , }, } const customFetch = axios.create({ baseURL: 'http://127.0.0.1:5050', }); export const registerUser = createAsyncThunk( 'user/registerUser', async (user, thunkAPI) => { try { const resp=await customFetch.post('/api/user/register', user, config); return resp.data ; }catch (error) { return thunkAPI.rejectWithValue(error.response.data.msg); } } );
Flask后端已配置:
CORS(app)
还额外添加了请求后钩子:
@app.after_request def add_security_headers(resp): resp.headers['Access-Control-Allow-Origin']='*' resp.headers['Access-Control-Allow-Methods']='GET, POST, PUT, OPTIONS' resp.headers["Access-Control-Allow-Headers"]="Access-Control-Request-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Access-Control-Allow-Origin, Origin, X-Requested-With, Content-Type, Accept" return resp
但使用原生fetch请求可正常工作:
await fetch(`${api_host}/api/user/register`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ // 数据内容 }), });
更新补充请求响应头:
常规信息
Request URL: http://127.0.0.1:5050/api/user/register Request Method: POST Status Code: 500 Referrer Policy: strict-origin-when-cross-origin
请求头
POST /api/user/register HTTP/1.1 Accept: application/json, text/plain, */* Accept-Encoding: gzip, deflate, br Accept-Language: en-GB,en;q=0.9,en-US;q=0.8 Access-Control-Allow-Origin: * Connection: keep-alive Content-Length: 110 Content-Type: application/json DNT: 1 Host: 127.0.0.1:5050 Origin: http://localhost:3000 Referer: http://localhost:3000/ Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: cross-site User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.27 sec-ch-ua: "Microsoft Edge";v="105", " Not;A Brand";v="99", "Chromium";v="105" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows"
响应头
HTTP/1.0 500 INTERNAL SERVER ERROR Content-Type: text/html; charset=utf-8 X-XSS-Protection: 0 Connection: close Server: Werkzeug/2.0.0 Python/3.8.10 Date: Fri, 09 Sep 2022 17:52:09 GMT
排查与解决方案
- 先解决后端500错误:从响应头看到状态码是500,说明注册接口内部抛出异常,导致Flask的
after_request钩子未执行(钩子仅在请求正常完成时触发),因此没有返回CORS头,浏览器才报CORS错误。查看Flask运行日志,定位500错误的具体原因(如参数校验失败、数据库连接错误、代码逻辑bug等),优先修复该后端问题。 - 移除前端请求中的
Access-Control-Allow-Origin头:这个头是后端返回给浏览器的,前端请求时添加完全无效,反而可能引发不必要的校验。修改后的前端配置:const config = { headers: { "Content-Type": "application/json" , }, } - 检查Flask-CORS的初始化顺序:确保
CORS(app)在所有路由定义之前执行,否则扩展无法为路由添加CORS支持。正确的初始化顺序示例:from flask import Flask from flask_cors import CORS app = Flask(__name__) CORS(app) # 先初始化CORS # 再定义路由 @app.route('/api/user/register', methods=['POST']) def register(): # 注册逻辑 pass - 处理异常请求的CORS头:如果后端偶尔会抛出异常,需要为错误响应也添加CORS头,避免浏览器报错。可以添加全局错误处理器:
from flask import make_response @app.errorhandler(500) def handle_internal_error(error): resp = make_response("服务器内部错误", 500) resp.headers['Access-Control-Allow-Origin'] = '*' resp.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, OPTIONS' resp.headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept" return resp - 统一主机地址:前端使用
localhost:3000,后端用127.0.0.1:5050,部分浏览器可能将这两个视为不同源。可以把Axios的baseURL改为http://localhost:5050,保持主机地址一致。
内容的提问来源于stack exchange,提问作者John Kendall
相关产品推荐
相关产品推荐

