Flask接收Ajax POST请求报400错误,如何正确传递JSON数据?
问题分析与解决方案
你遇到的400 Bad Request错误主要有两个原因:
- Flask路由中尝试获取
request.form['task_id'],但AJAX发送的参数键是id而非task_id,导致参数找不到抛出KeyError; - 使用
request.get_data()获取的是整个请求体的原始字节(如b'time=3&id=9'),这不是你需要的单独time值,会导致数据库存储错误数据。
以下是两种可行的解决方案:
方案一:使用表单编码格式(简单易上手)
保持jQuery默认的表单编码格式,适配Flask的request.form解析。
修改Flask路由代码
@app.route('/timer/', methods=["POST"]) @login_required def timer(): """ Handle saving timer""" if request.method == "POST": # 从表单数据中获取对应参数 time = request.form.get('time') task_id = request.form.get('id') # 校验参数完整性 if not time or not task_id: return jsonify(success=False, message="缺少时间或任务ID"), 400 # 根据数据库字段类型转换time格式(示例为整数) try: time = int(time) except ValueError: return jsonify(success=False, message="时间格式无效"), 400 # 执行数据库更新(记得添加db.commit()提交事务,根据你的DB配置调整) db.execute("UPDATE tasks SET charge = ? WHERE task_id = ? AND user_id = ?", time, task_id, session["user_id"]) db.commit() # AJAX请求建议返回JSON响应,而非redirect return jsonify(success=True, message="时间已成功保存")
JavaScript代码无需修改
jQuery会自动将data对象编码为表单格式,与Flask的request.form兼容。
方案二:使用JSON格式传递数据(满足你的需求)
如果需要严格以JSON格式传递数据,需调整AJAX请求头和数据格式,同时修改Flask的解析方式。
修改JavaScript函数
function charge_time(btn_id) { clearInterval(state.interval); $.ajax({ type: "POST", dataType: "json", contentType: "application/json", // 告知服务器请求体为JSON格式 url: "/timer/", data: JSON.stringify({ time : state.time, id: btn_id }), // 将对象转为JSON字符串 success: function(data) { console.log(data); if (data.success) { alert("时间已保存"); // 可在此添加页面刷新或其他逻辑 } }, error: function(xhr) { console.error("请求失败:", xhr.responseText); } }); state.time = 0; stopwatch.classList.replace("active", "inactive"); }
修改Flask路由代码
@app.route('/timer/', methods=["POST"]) @login_required def timer(): """ Handle saving timer""" if request.method == "POST": # 解析JSON格式的请求体 data = request.get_json() if not data: return jsonify(success=False, message="无效的JSON数据"), 400 time = data.get('time') task_id = data.get('id') # 校验参数完整性 if not time or not task_id: return jsonify(success=False, message="缺少时间或任务ID"), 400 # 转换time格式 try: time = int(time) except ValueError: return jsonify(success=False, message="时间格式无效"), 400 # 执行数据库更新并提交事务 db.execute("UPDATE tasks SET charge = ? WHERE task_id = ? AND user_id = ?", time, task_id, session["user_id"]) db.commit() return jsonify(success=True, message="时间已成功保存")
额外注意事项
- 你的按钮设置了
type="button",不会触发表单的默认提交行为,无需担心嵌套表单的冲突问题; - AJAX是异步请求,Flask返回
redirect('/')对前端无作用,建议返回JSON响应由JavaScript处理后续逻辑; - 数据库操作后需调用
db.commit()(根据你的数据库连接配置调整),否则修改不会持久化到数据库。
内容的提问来源于stack exchange,提问作者Błażej Błażej
相关产品推荐
相关产品推荐

