JavaScript fetch发POST变为OPTIONS且Flask收不到请求数据如何解决
问题原因
- OPTIONS请求是浏览器CORS预检机制触发的:你发送的是带
Content-Type: application/json的跨域POST请求,不属于浏览器定义的简单请求范畴,因此浏览器会自动先发送OPTIONS预检请求,验证服务端是否允许该跨域请求。如果服务端没有正确响应OPTIONS请求,后续真实的POST请求就不会发出,这也是你代码中console.log("Success")不会执行、服务端拿不到请求数据的核心原因。 - 服务端无法接收数据:除了预检失败导致POST请求未发出之外,Flask默认无法直接从
application/json格式的请求体中取数,需要调用对应方法解析。
解决方案
1. 服务端处理CORS预检
优先使用官方适配的flask-cors库快速解决跨域问题:
首先安装依赖:pip install flask-cors
然后修改Flask服务端代码:
from flask import Flask, request from flask_cors import CORS app = Flask(__name__) # 全局开启跨域支持,开发环境使用足够 CORS(app, supports_credentials=True) # 路由显式声明支持OPTIONS方法 @app.route('/api/login', methods=['POST', 'OPTIONS']) def login(): # 预检请求直接返回200状态码即可 if request.method == 'OPTIONS': return {}, 200 # 解析JSON格式的请求体 req_data = request.get_json() username = req_data.get('username') password = req_data.get('password') # 此处编写你的登录校验逻辑 return {"code": 0, "msg": "登录成功"}
2. 前端fetch逻辑优化
fetch默认不会对4xx/5xx类的HTTP错误状态码抛出异常,建议增加异常判断逻辑方便排查问题:
fetch(`${url}/api/login`, { method: "POST", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({'username': username, 'password': password}) }) .then(response => { // 先判断请求是否成功 if (!response.ok) { throw new Error(`请求错误,状态码:${response.status}`) } return response.json() }) .then(res => { console.log("Success", res) }) .catch(err => { console.error("请求失败:", err) })
内容的提问来源于stack exchange,提问作者helleel
相关产品推荐
相关产品推荐

