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

Flask Ajax请求出现ImmutableMultiDict([]),表单验证失败求助

Flask Ajax 请求数据接收异常问题

前端已发送数据,但后端验证时得到ImmutableMultiDict([]),触发输入字段为空的验证错误,相关代码如下:

后端代码

@users.route('/updateUserPassword',methods=['POST'])
@login_required
def updateUserPassword() :
    message=''
    status=''
    print(request.form)
    passwordform = changeUserPassword(request.form)
    if passwordform.validate_on_submit() :
        id        = request.form.get('id')
        action    = request.form.get('action')
        password  = request.form.get('password')
        pass_confirm  = request.form.get('pass_confirm')
 
         
    else:   
       # return jsonify({'status':'error',
              #   message:[{passwordform[field].label.text: ', '.join(errors)} for field, errors in passwordform.errors.items()]})
        errors = {}
        for field, field_errors in passwordform.errors.items():
            errors[field] = [str(error) for error in field_errors]
        return jsonify({'error': "error submit data ", 'message': errors})

前端JS代码

$("#editUserForm").submit(function(){

var formData = $(this).serialize();
var allData  = formData + "&action=editPass";
$.ajax({
url: "{{ url_for('users.updateUserPassword') }} ",
  type:"POST",
  data: JSON.stringify(allData),
  contentType: 'application/json',

  beforeSend:function(){
  },
  statusCode: {
      404: function() {
          alert( "page not found" );
      },
  },
  success:function(valdata) {
  
      if(valdata['status'] == "success")
      {
          $("#updatePasswordResult").html(valdata['message']);
          setTimeout(function(){$('#changepassword').modal('hide');}, 2000);
      }else{
        var errors = valdata['message'];
                          for (var field in errors) {
                              if (errors.hasOwnProperty(field)) {
                                  var errorMessages = errors[field];
                                  for (var i = 0; i < errorMessages.length; i++) {
                                      $('#updatePasswordResult').append('<p>' + field + ': ' + errorMessages[i] + '</p>');
                                  }
                              }
                            }

        //  $("#updatePasswordResult").html(valdata['message']);
      }
  }
});
return false;
});

表单验证代码

class changeUserPassword(FlaskForm):

    password = PasswordField("Password",validators=[DataRequired()])                
    pass_confirm = PasswordField('Confirm Password',validators=[DataRequired(),EqualTo('password',message='Passwords must match!')])
   
    submit = SubmitField('Submit')  

问题原因及解决方案

核心问题是前后端数据格式不匹配:

  • 前端将序列化后的表单数据转为JSON字符串发送,并设置contentType: 'application/json'
  • 后端尝试用request.form接收数据,但request.form仅解析application/x-www-form-urlencoded编码的表单数据,无法解析JSON格式数据,因此得到空的ImmutableMultiDict

方法一:修改前端(推荐,符合表单提交常规逻辑)

取消JSON序列化,直接发送表单编码数据,并移除contentType设置(jQuery默认会设置为application/x-www-form-urlencoded):

修改后的前端代码:

$("#editUserForm").submit(function(){
    var formData = $(this).serialize();
    var allData  = formData + "&action=editPass";
    $.ajax({
        url: "{{ url_for('users.updateUserPassword') }} ",
        type:"POST",
        data: allData,
        beforeSend:function(){
        },
        statusCode: {
            404: function() {
                alert( "页面未找到" );
            },
        },
        success:function(valdata) {
            if(valdata['status'] == "success")
            {
                $("#updatePasswordResult").html(valdata['message']);
                setTimeout(function(){$('#changepassword').modal('hide');}, 2000);
            }else{
                var errors = valdata['message'];
                for (var field in errors) {
                    if (errors.hasOwnProperty(field)) {
                        var errorMessages = errors[field];
                        for (var i = 0; i < errorMessages.length; i++) {
                            $('#updatePasswordResult').append('<p>' + field + ': ' + errorMessages[i] + '</p>');
                        }
                    }
                }
            }
        }
    });
    return false;
});

方法二:修改后端(适配JSON格式请求)

如果需要保留前端的JSON发送方式,后端需用request.get_json()解析JSON数据,并传给FlaskForm:

修改后的后端代码:

@users.route('/updateUserPassword',methods=['POST'])
@login_required
def updateUserPassword() :
    message=''
    status=''
    # 获取JSON数据,无数据时返回空字典
    request_data = request.get_json() or {}
    print(request_data)
    passwordform = changeUserPassword(request_data)
    if passwordform.validate_on_submit() :
        id        = request_data.get('id')
        action    = request_data.get('action')
        password  = request_data.get('password')
        pass_confirm  = request_data.get('pass_confirm')
        # 此处添加密码更新逻辑
        return jsonify({'status':'success', 'message':'密码更新成功'})
    else:   
        errors = {}
        for field, field_errors in passwordform.errors.items():
            errors[field] = [str(error) for error in field_errors]
        return jsonify({'error': "提交数据错误", 'message': errors})

内容的提问来源于stack exchange,提问作者Ahmed Gaber

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 05:07:35