使用FormData通过Ajax提交含图片表单时返回JSON字符串而非跳转问题
解决FormData Ajax提交后跳转到空白JSON页面的问题
你遇到的核心问题是表单的原生提交行为没有被正确拦截,再加上FormData的初始化方式有误,导致Ajax提交和原生表单提交同时触发——原生提交会直接把Action返回的JSON当成页面内容显示,这就是你看到空白页显示{success = true}的原因。下面一步步帮你修正:
核心问题分析
- FormData初始化错误:你当前的写法
new FormData($('form', dialog)).get(0)是错误的,FormData需要接收一个表单DOM元素,而非jQuery对象,正确写法应该是取jQuery对象对应的DOM元素。 - FormData获取时机不对:你在
bindForm函数初始化时就获取了FormData,但此时用户还没在弹窗里输入内容或选择文件,导致提交的是旧数据。 - 默认提交行为未彻底阻止:虽然你在submit事件里return false,但如果前面的代码出错(比如FormData初始化失败),原生提交还是会触发。
修正后的Ajax代码
把你的bindForm函数改成这样:
function bindForm(dialog) { $('form', dialog).submit(function (e) { // 先彻底阻止表单的原生提交行为 e.preventDefault(); $('#progress').show(); // 实时获取表单DOM元素创建FormData,确保拿到最新的用户输入和文件 var formdata = new FormData(this); $.ajax({ url: this.action, type: this.method, data: formdata, contentType: false, processData: false, success: function (result) { $('#progress').hide(); if (result.success) { $('#myModal').modal('hide'); location.reload(); // 刷新页面显示新内容 } else { // 如果验证失败,重新加载弹窗内容 $('#myModalContent').html(result); bindForm(dialog); // 注意这里要传dialog参数,否则找不到表单 } }, error: function() { // 处理Ajax请求失败的情况 $('#progress').hide(); alert('提交失败,请重试'); } }); // 额外保险,阻止默认行为 return false; }); }
关键修改点解释
- 用
e.preventDefault()在最开头就阻止原生提交,避免代码出错时的 fallback 问题。 - 在submit事件内部创建FormData,用
this(当前表单DOM元素)作为参数,确保拿到最新的表单数据和文件。 - 修正了
bindForm()递归调用时的参数问题,之前没传dialog会导致找不到弹窗里的表单。 - 增加了error回调,方便排查Ajax请求失败的情况。
后端Action的小优化(可选)
你的Action代码基本没问题,不过可以简化文件获取逻辑——因为模型里已经有Images属性,只要表单里的文件name是Images(你已设置name="Images"),ASP.NET MVC会自动绑定到model.Images,不需要手动从Request.Files取:
[HttpPost] [ValidateAntiForgeryToken] public JsonResult CreateArticles(ArticlesCustomClass model) { if (ModelState.IsValid) { // 直接用model.Images即可,不需要手动从Request.Files读取 ArticlesData.CreateArticles(model, model.Images); return Json(new { success = true }); } // 如果验证失败,返回ModelState的错误信息,前端可友好显示 return Json(new { success = false, errors = ModelState.Values.SelectMany(v => v.Errors.Select(e => e.ErrorMessage)) }); }
最后检查点
- 确保jQuery版本支持FormData(jQuery 1.6+基本都支持,建议用较新版本)。
- 确认表单的
enctype="multipart/form-data"已正确设置(你已添加,没问题)。 - 弹窗里的文件输入框name是
Images,和模型属性名一致(你已设置,没问题)。
这样修改后,Ajax就能正确拦截表单提交,提交成功后会关闭弹窗并刷新页面,不会再出现空白页显示JSON的情况了。
内容的提问来源于stack exchange,提问作者lekinio
相关产品推荐
相关产品推荐

