Flask+Ajax上传图片表单数据为空,验证失败求助
Flask + Ajax 上传图片表单数据为空问题
我是Flask新手,尝试用Ajax和FormData上传图片,但表单数据总是为空,后端因为必填字段验证失败卡住。选了图片发送也没用,查了很多方案都没解决,相关代码如下:
后端代码
@presentation.route('/presentation/updateImage',methods=['POST']) @login_required def updateImage() : UpdateImageForm = UpdateImage(request.form) if UpdateImageForm.validate_on_submit() : image = request.json.get("image") print(image) return jsonify({'status': "success", 'message': 'Password Changed Successfuly','id':image}) else: errors = {} for field, field_errors in UpdateImageForm.errors.items(): errors[field] = [str(error) for error in field_errors] return jsonify({'status': "errors ", 'message': errors})
前端表单代码
<div class="modal fade" id="update-img" tabindex="-1" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered1 modal-simple modal-add-new-cc"> <div class="modal-content p-3 p-md-5"> <div class="modal-body"> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <div class="text-center mb-4"> <h3 class="mb-2">Change Image</h3> </div> <form id="updateImage" method="POST" class="row g-3" enctype="multipart/form-data"> {{UpdateImageForm.hidden_tag()}} <label class="form-label" for="bs-validation-upload-file">Presntaion Images</label> <div class="mb-3"> {{ UpdateImageForm.image(class_="form-control") }}<br> </div> <div class="col-12 text-center"> <button type="submit" class="btn btn-primary me-sm-3 me-1">Submit</button> <button type="reset" class="btn btn-label-secondary btn-reset" data-bs-dismiss="modal" aria-label="Close"> Cancel </button> </div> </form> </div> </div> </div> </div>
JS代码
// start edit image $(".table_for_data").on( 'click', '.editImage', function () { $("#updateImageResult").html(""); // get id for update var myId = $(this).attr("data-id"); // alert(myId) $("#updateImage").submit(function(e){ e.preventDefault() var form_data = new FormData($('#updateImage')[0]); $.ajax({ url: "{{ url_for('presentation.updateImage') }} ", type: "POST", data: JSON.stringify(form_data), contentType: 'application/json', beforeSend:function(){ $(".loadingImage").show(); }, statusCode: { 404: function() { alert( "page not found" ); }, }, success:function(valdata) { alert('success') } }); return false; }); });
问题分析与修正方案
核心错误点
JS端错误
- 用
JSON.stringify(form_data)序列化FormData:文件无法被转成JSON,直接导致后端接收不到任何文件数据 - 手动设置
contentType: 'application/json':文件上传需要multipart/form-data格式,强制JSON会破坏请求结构 - 未设置
processData: false:jQuery默认会把FormData转成urlencoded格式,导致文件数据损坏 - 重复绑定submit事件:每次点击
.editImage都会新增一个submit监听,多次点击后会触发多次提交 - 请求URL末尾多了空格:可能导致路径匹配失败
- 用
后端错误
- 用
request.form初始化表单:文件字段不在request.form里,应该让FlaskForm自动处理multipart/form-data - 用
request.json.get("image")获取图片:请求不是JSON格式,文件需要从request.files中获取
- 用
修正后的代码
修正后的JS代码
// 编辑图片事件 $(".table_for_data").on('click', '.editImage', function () { $("#updateImageResult").html(""); var myId = $(this).attr("data-id"); // 先解绑之前的submit事件,避免重复提交 $("#updateImage").off('submit').on('submit', function(e){ e.preventDefault(); var form_data = new FormData($('#updateImage')[0]); // 把需要传递的ID加入FormData form_data.append('id', myId); $.ajax({ url: "{{ url_for('presentation.updateImage') }}", type: "POST", data: form_data, contentType: false, // 让浏览器自动设置正确的multipart/form-data请求头 processData: false, // 禁止jQuery处理FormData,避免数据损坏 beforeSend:function(){ $(".loadingImage").show(); }, statusCode: { 404: function() { alert("页面未找到"); }, }, success:function(valdata) { alert('图片更新成功'); // 可在此处添加刷新页面或图片的逻辑 }, error: function(xhr) { // 打印错误信息便于调试 console.log(xhr.responseJSON); } }); return false; }); });
修正后的后端代码
@presentation.route('/presentation/updateImage', methods=['POST']) @login_required def updateImage(): # 无需手动传request.form,FlaskForm会自动处理multipart/form-data update_form = UpdateImage() if update_form.validate_on_submit(): # 从request.files中获取上传的文件对象 image_file = request.files.get('image') if image_file and image_file.filename.strip() != '': # 此处可添加文件保存逻辑,示例: # import os # save_path = os.path.join(app.config['UPLOAD_FOLDER'], image_file.filename) # image_file.save(save_path) return jsonify({'status': "success", 'message': '图片更新成功', 'filename': image_file.filename}) else: return jsonify({'status': "error", 'message': '请选择有效的图片文件'}) else: errors = {} for field, field_errors in update_form.errors.items(): errors[field] = [str(error) for error in field_errors] return jsonify({'status': "errors", 'message': errors})
补充正确的表单类定义(如果还没写)
from flask_wtf import FlaskForm from flask_wtf.file import FileField, FileRequired, FileAllowed class UpdateImage(FlaskForm): image = FileField('演示图片', validators=[ FileRequired(message='请选择要上传的图片'), FileAllowed(['jpg', 'jpeg', 'png'], message='仅支持JPG、PNG格式的图片') ])
内容的提问来源于stack exchange,提问作者Ahmed Gaber
相关产品推荐
相关产品推荐

