AJAX 提交带有文件上传的表单。
AJAX 提交带有文件上传的表单。
我正在使用jQuery和Ajax来提交数据和文件,但我不确定如何在一个表单中同时发送数据和文件。
目前我用两种方法几乎完全相同,但数据收集到数组中的方式不同,数据使用.serialize();
,而文件使用= new FormData($(this)[0]);
是否可能将两种方法结合起来,通过Ajax在一个表单中上传文件和数据?
Data jQuery,Ajax和html
$("form#data").submit(function(){ var formData = $(this).serialize(); $.ajax({ url: window.location.pathname, type: 'POST', data: formData, async: false, success: function (data) { alert(data) }, cache: false, contentType: false, processData: false }); return false; });
Files jQuery,Ajax和html
$("form#files").submit(function(){ var formData = new FormData($(this)[0]); $.ajax({ url: window.location.pathname, type: 'POST', data: formData, async: false, success: function (data) { alert(data) }, cache: false, contentType: false, processData: false }); return false; });
如何将上述内容组合在一起,以便我可以通过Ajax在一个表单中发送数据和文件?
我的目标是能够通过一个post请求将整个表单发送,这是可能的吗?
AJAX提交带有文件上传的表单的问题出现的原因是无法直接使用AJAX提交包含文件的表单。解决方法是使用iframe,并将表单的目标设置为该iframe。
下面是一个使用jQuery的示例代码:
function ajax_form($form, on_complete) { var iframe; if (!$form.attr('target')) { //为表单创建一个唯一的iframe iframe = $("").attr('name', 'ajax_form_' + Math.floor(Math.random() * 999999)).hide().appendTo($('body')); $form.attr('target', iframe.attr('name')); } if (on_complete) { iframe = iframe || $('iframe[name="' + $form.attr('target') + '"]'); iframe.load(function () { //获取服务器响应 var response = iframe.contents().find('body').text(); on_complete(response); }); } }
这种方法在所有浏览器上都可以正常工作,不需要对数据进行序列化或准备。缺点是无法监控进度。另外,至少对于Chrome浏览器来说,请求不会出现在开发者工具的“xhr”选项卡下,而是在“doc”选项卡下。
虽然这种方法实际上不是使用AJAX,但对于有同样问题的人来说仍然有用。
问题原因:使用了错误的jQuery标识符。
解决方法:使用正确的jQuery标识符。
在使用AJAX进行文件上传时,可以使用一个表单同时上传数据和文件。
使用PHP + HTML实现:
使用jQuery + Ajax实现:
$("form#data").submit(function(e) { e.preventDefault(); var formData = new FormData(this); $.ajax({ url: window.location.pathname, type: 'POST', data: formData, success: function (data) { alert(data) }, cache: false, contentType: false, processData: false }); });
简洁版本:
$("form#data").submit(function(e) { e.preventDefault(); var formData = new FormData(this); $.post($(this).attr("action"), formData, function(data) { alert(data); }); });
以上方法能正常工作,但我需要在响应中显示"文件上传成功,感谢上传",但是我得到的响应中有<br/>标签,如何解决这个问题?
不要使用Internet Explorer?......说真的,我不知道,我很确定它对我有效,尝试更详细地调试问题,什么不能正常工作?为什么你有两个账户?
在IE 8或9中,这个解决方案将不起作用,因为FormData是一个HTML5对象,不在IE 8或9中存在。
如何在没有form
的情况下获取文件?
$(this)[0]
只是this
的别名,所以new FormData(this)
就足够了。
似乎无法检查FormData对象,请参考这个问题(对于任何遇到与我一样无能为力的人,因为该对象始终为空)。
对于将来的读者:contentType和processData声明很重要。更多信息请参见这个答案。
我尝试了你答案中的简洁方法,但对我来说似乎没有起作用。然而,使用async : false的长版本起作用了。-------我在使用文件://和canJS的can.fixture()模拟post终点。
在移动端(单线程)浏览器上,不需要async: false
,它会导致阻塞。
你知道后端开发人员如何从这个请求中获取表单文件和表单数据吗?
cache选项似乎不是必需的。简洁版本对我不起作用。
IE<10有没有回退解决方案?
在我的情况下,我必须使用contentType: "application/octet-stream"
。
- 那会破坏一些东西。你需要contentType: false
。
- 不完全是这样。唯一的方法是使用隐藏的iframe技巧。......但是这些浏览器多年来没有接收到任何安全更新,并且它们的市场份额很小。
- 与任何普通的多部分表单提交相同。具体细节取决于编程语言和表单处理库。
我确实最终使用了contentType: false
,同时在服务器端也使用了文件输入上的name
属性。
我使用这个解决方案,但似乎表单只提交了文件而没有提交中的值,有什么建议可以查看吗?
请注意,较短的版本可能会出现非法调用的问题,你可能需要设置contentType
和processData
,就像较长的版本一样。
在ASP.Net MVC中,我遇到了使用HttpPostedFileBase上传文件的问题。我需要在按钮点击时执行一些操作,然后如果一切正常再提交表单。下面是我解决这个问题的方法:
$(".submitbtn").on("click", function(e) { var form = $("#Form"); var formData = new FormData(form[0]); if ($(form).valid()) { $.ajax({ type: "POST", url: $(form).prop("action"), data: formData, contentType: false, processData: false, error: ErrorHandler, success: successHandler }); } });
以上代码会正确地填充我的MVC模型,请确保在模型中,HttpPostedFileBase[]属性的名称与HTML中的输入控件的名称相同,例如:
public class MyViewModel { public HttpPostedFileBase[] UploadedFiles { get; set; } }
在我的情况下,我需要使用contentType : "application/octet-stream"
。
非常感谢你,你节省了我很多时间。