JavaScript Fetch API与Python Flask请求头问题:POST JSON返回None
问题分析与解决方案
你的问题根源出在**mode: 'no-cors'**这个fetch配置上,这也是为什么Postman能正常工作但浏览器里的fetch不行的核心原因。
为什么mode: 'no-cors'会导致问题?
当你启用no-cors模式时,浏览器会强制执行严格的跨域请求限制:
- 它会将请求变为"不透明请求",浏览器不会暴露响应内容给你的代码
- 更关键的是,自定义的
Content-Type: application/json会被浏览器过滤掉,实际发送的请求头里的Content-Type会被替换成text/plain
Flask的request.get_json()默认只会解析Content-Type为application/json的请求,所以当请求头里的Content-Type不对时,就会返回None——这和你用force=True能绕过检查拿到数据的现象完全吻合。
而Postman不是浏览器环境,不受同源策略限制,它能完整发送你设置的Content-Type头,所以Flask可以正常解析。
正确的解决方案
不要用no-cors模式来处理跨域问题,正确的做法是在Flask后端配置CORS支持,同时修改fetch代码去掉mode: 'no-cors'。
1. 修改JavaScript的fetch代码
去掉mode: 'no-cors'配置,让浏览器发送标准的跨域请求:
const SERVER_URL = 'http://localhost:8080/route'; fetch(SERVER_URL, { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify({"hello": "world"}) });
2. 在Flask后端配置CORS
首先安装flask-cors扩展:
pip install flask-cors
然后修改你的Flask代码,添加CORS支持:
from flask import Flask from flask import request from flask_cors import CORS app = Flask(__name__) # 允许所有域名的跨域请求(开发环境可以这么用,生产环境建议配置具体域名) CORS(app) @app.route('/route', methods = ['POST']) def routeHandler(): data = request.get_json() print(data) # 现在应该能正常打印{"hello": "world"}了 return 'got it' if __name__ == '__main__': app.run(port = 8080)
这样修改后,浏览器的fetch请求就能正常发送Content-Type: application/json头,Flask的request.get_json()也能正确解析出JSON数据了。
内容的提问来源于stack exchange,提问作者Carpetfizz
相关产品推荐
相关产品推荐

