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
相关产品推荐
相关产品推荐

