通过AJAX(jQuery / Node.js)提交包含文件字段的表单

时间:2013-04-07 07:24:06

标签: jquery ajax forms file-upload

我有一个包含单个文件字段的表单:

<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)来解决这个问题,但是有一种更清洁的方式,我没有看到它吗?

2 个答案:

答案 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,或者您无法控制它们,则可以使用文件上传插件,例如UploadifyjQuery.formFineUploader,.. 。它将测试浏览器的功能并使用最合适的技术。

答案 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和插件都很好用。

希望这有助于某人!我没有发现插件网站上的文档像我希望的那样友好。