jsonify可直接传状态码作为第二参数,如jsonify({"error": "not found"}, 404);仅支持dict/list等可序列化类型,不可传模型实例或datetime。

Flask里用jsonify返回JSON,响应头和状态码怎么一起设
jsonify默认返回200 OK,但接口经常要返回400、404或500。直接在jsonify()后面链式调用.status_code = 400不行——它返回的是Response对象,但赋值后没生效,得用make_response或直接传参。
- 正确做法是把状态码作为
jsonify()的第二个参数:jsonify({"error": "not found"}, 404) - 或者用
make_response(jsonify(...))再设.status_code,但多了一层包装,不必要 - 注意:状态码必须是整数,不能是字符串
"404",否则会抛TypeError: status code must be an integer - 如果返回空JSON(比如
jsonify({})),状态码仍可正常传参:jsonify({}, 201)
为什么不用json.dumps() + Response手动构造
有人图灵活,自己用json.dumps()序列化再包一层Response,还手动设Content-Type: application/json。这容易漏掉几件事:
-
json.dumps()默认不处理中文,会变成\u4f60\u597d,得加ensure_ascii=False -
Response默认Content-Type是text/html,不设就成text/plain,前端可能解析失败 -
jsonify自动做了ensure_ascii=False、Content-Type设为application/json、还支持datetime等常见类型序列化(虽然有限,但比裸dumps强) - 性能上差别极小,
jsonify只是薄封装,没额外开销
jsonify对嵌套字典、列表、None的处理边界
jsonify只接受字典或列表作为第一参数,其他类型(比如字符串、数字、None)会报TypeError: Object of type ... is not JSON serializable。
- 想返回纯字符串?不行:
jsonify("hello")→ 报错;得包装成字典:jsonify(msg="hello") - 想返回
None?也不行:jsonify(None)→ 报错;可用jsonify(result=None)或jsonify({}) - 嵌套结构没问题:
jsonify({"data": [{"id": 1}, {"id": 2}], "total": 2})完全OK - 但别传
datetime对象进去:jsonify({"created": datetime.now()})→ 报错;要么提前转成字符串,要么用自定义JSONEncoder
调试时看到500 Internal Server Error但没日志?检查jsonify参数类型
本地开发时,如果接口突然返回空白页+500,且控制台没报错,大概率是jsonify传了不可序列化对象,而Flask在生产模式下默认不显示详细错误。
立即学习“Python免费学习笔记(深入)”;
- 典型诱因:
jsonify(user_obj),其中user_obj是SQLAlchemy模型实例,不是字典 - 验证方法:在视图函数里先
print(type(user_obj))或print(user_obj.__dict__),确认是否可直接序列化 - 快速修复:用
vars(user_obj)或user_obj.to_dict()(如果你写了这个方法),再喂给jsonify - 更稳的做法:始终确保传给
jsonify的是纯Python数据结构(dict、list、str、int、float、bool、None)
最常被忽略的其实是参数类型检查——jsonify看着简单,但只要混进一个模型实例、一个Decimal、一个未处理的datetime,它就静默崩给你看,连错误堆栈都藏在WSGI层底下。










