本文详解 flask 中因缺失 content-type: application/json 请求头导致 request.get_json() 返回 none 的典型问题,并提供完整可运行的修复方案、客户端调用示例及关键注意事项。
本文详解 flask 中因缺失 content-type: application/json 请求头导致 request.get_json() 返回 none 的典型问题,并提供完整可运行的修复方案、客户端调用示例及关键注意事项。
在使用 Flask 构建 RESTful API 时,若后端通过 request.get_json() 解析客户端提交的 JSON 数据,但始终返回 None 或触发 Did not attempt to load JSON data because the request Content-Type was not ‘application/json’ 警告,根本原因在于:Flask 默认仅在请求头明确声明 Content-Type: application/json 时,才尝试解析请求体为 JSON 对象。即使你使用 requests.post(…, json=…),它虽会自动序列化数据并设置 Content-Type,但在某些调试场景(如手动构造请求、前端 fetch 未设 header、或中间代理覆盖)下该头可能丢失。
以下是一个修复后的完整服务端示例(含健壮性增强):
GPT plus 代充 只需 145from flask import Flask, jsonify, request from flask_restful import Api, Resource
app = Flask(name) api = Api(app)
class Main(Resource):
def get(self): # 示例:模拟从数据库获取电影数据 movie_data_list = [ {"id": 1, "title": "加勒比海盗", "actor": "约翰尼·德普"}, {"id": 2, "title": "剪刀手爱德华", "actor": "约翰尼·德普"}, {"id": 3, "title": "查理和巧克力工厂", "actor": "约翰尼·德普"} ] return jsonify({"movies": movie_data_list}) def post(self): # 关键:显式指定 force=True 可绕过 Content-Type 检查(仅用于调试/兼容场景) # 更推荐方式:确保客户端发送正确 header(见下方说明) data_from_client = request.get_json(silent=True) # silent=True 避免 400 错误 if data_from_client is None: return jsonify({ "error": "Invalid JSON payload or missing Content-Type: application/json header" }), 400 # ✅ 安全处理:验证必需字段 query = data_from_client.get("name") if not isinstance(query, str) or not query.strip(): return jsonify({"error": "Missing or invalid 'name' field"}), 400 # 此处可接入 LLM 调用、数据库查询等业务逻辑 # 示例响应(实际应替换为 GPT 处理 + DatabaseData 查询) response = { "query": query, "suggested_movies": [ {"title": "加勒比海盗:黑珍珠号的诅咒", "year": 2003}, {"title": "爱德华剪刀手", "year": 1990}, {"title": "理发师陶德", "year": 2007} ], "status": "success" } return jsonify(response)
api.add_resource(Main, "/movie_gpt_ai/back/moviedata")
if name == "main":
GPT plus 代充 只需 145app.run(debug=True, port=1000, host='localhost')
对应客户端调用(Python requests),必须显式设置 Content-Type 头(尽管 json= 参数通常已自动设置,但显式声明更清晰、可调试):
import requests
✅ 正确写法:显式声明 headers(推荐)
headers = {"Content-Type": "application/json"} res = requests.post(
GPT plus 代充 只需 145"http://localhost:1000/movie_gpt_ai/back/moviedata", json={"name": "Три лучших фильма с Джонни Депом"}, headers=headers
) print("POST Response:", res.json())
✅ GET 请求不受影响(无需 Content-Type)
res_get = requests.get("http://localhost:1000/movie_gpt_ai/back/moviedata") print("GET Response:", res_get.json())
⚠️ 重要注意事项:
- requests.post(url, json=…) 默认会自动设置 Content-Type: application/json,因此多数情况下无需手动加 headers。但如果遇到问题,请用抓包工具(如 Wireshark、浏览器 DevTools Network 面板)确认请求头是否真实发出;
- 避免滥用 force=True(如 request.get_json(force=True)),它会强制解析 body 为 JSON,即使 Content-Type 是 text/plain,这会掩盖真实问题,降低接口安全性与可维护性;
- 前端 JavaScript 使用 fetch 时,务必手动设置:
fetch("http://localhost:1000/movie_gpt_ai/back/moviedata", {
GPT plus 代充 只需 145method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: "Три лучших фильма с Джонни Депом" })
})
总结:该问题本质是 HTTP 协议规范与 Flask 设计哲学的体现——内容类型需由客户端明确声明,服务端不猜测。坚持“客户端负责正确声明,服务端负责严格校验”的原则,是构建可靠 API 的基石。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/243899.html