You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask接收Ajax POST请求报400错误,如何正确传递JSON数据?

问题分析与解决方案

你遇到的400 Bad Request错误主要有两个原因:

  1. Flask路由中尝试获取request.form['task_id'],但AJAX发送的参数键是id而非task_id,导致参数找不到抛出KeyError;
  2. 使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 23:28:00