我有一个包含单个文件字段的表单:
<form id="myForm" action="/processFile" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile">
</form>
我想通过AJAX提交表单(在客户端使用jQuery,在服务器端使用Node.JS)。
这是我在jQuery中首先在客户端尝试的(在查看类似Submit form via AJAX in jQuery之类的问题之后):
submitButton.on('click', function(ev) {
$.ajax({
type: "GET",
url: $('#myForm').action
data: { form: $('#myForm').seralize() }
}).done(function(res) {
$('#targetDiv').html(res);
});
});
可悲的是,这不起作用,因为.seralize()方法不适用于文件输入。
所以我决定实际发布表单是最好的路由,因为它处理将文件上传到服务器的异步混乱。所以我尝试了这个:
submitButton.on('click', function(ev) {
$('#myForm').submit(function(err) {
$.ajax({
type: "GET",
url: $('#myForm').action
data: { form: $('#myForm').seralize() }
}).done(function(res) {
$('#targetDiv').html(res);
});
});
});
即,(1)实际提交表单,然后(2)在表单提交的回调中进行我的ajax调用。
遗憾的是,这也不起作用,因为提交表单需要根据“/ processFile”的响应重新加载整个页面。
我想要的是(1)提交文件输入尽可能简单通过AJAX ,以及(2)使用URL的响应注入一些偏HTML。看起来你可以使用一些iFrame技巧(比如这个http://www.jainaewen.com/files/javascript/jquery/iframe-post-form.html)来解决这个问题,但是有一种更清洁的方式,我没有看到它吗?
答案 0 :(得分:2)
如果您使用的浏览器支持HTML5,您可以使用新的XMLHttpRequest
对象来实现该目标。您的代码可能如下所示:
submitButton.on('click', function(ev) {
var form = $('form')[0];
var fd = new FormData(form);
var xhr = new XMLHttpRequest();
xhr.open(form.method, form.action, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
// handle success case
}
};
xhr.send(fd);
return false;
});
如果您的客户端浏览器尚不支持HTML5,或者您无法控制它们,则可以使用文件上传插件,例如Uploadify
,jQuery.form
,FineUploader
,.. 。它将测试浏览器的功能并使用最合适的技术。
答案 1 :(得分:1)
我最终只是通过插件使用iframe技巧:http://www.jainaewen.com/files/javascript/jquery/iframe-post-form.html
以下是我的代码:
表格:
<form id="myForm" action="/processFile" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile">
<input type="submit" id="mySubmitButton" style="display: none;">
</form>
...
<button id="continueButton">Continue</button>
请注意,出于无趣的原因,我想要一个必须驻留在表单外面的按钮来进行提交。
JS:
$('#continueButton').on('click', function(ev) {
// I click the hidden submit inside the form
$('#mySubmitButton').click();
});
$('#myForm').iframePostForm ({
json : false // my server response is straight HTML
, post : function() {
// initiation of waiting sequence
return true; // returning false aborts the submit
}
, complete : function(res) {
$('#targetDiv').html(res); // I stick the response in the target div
}
});
让我感到震惊的一件事是这个插件的实现方式,只需要调用
$('#myForm').submit();
在continueButton的onclick内部不起作用。直接触发form.submit()必须以某种不好的方式绕过jQuery的事件处理。所以我的解决方法(正如你所看到的)是在表单中放置一个不可见的表单提交按钮,并点击我的外部按钮。这似乎与jQuery和插件都很好用。
希望这有助于某人!我没有发现插件网站上的文档像我希望的那样友好。