如何使用jQuery异步上传文件?

我想用jQuery异步上传文件。

$(document).ready(function () {
    $("#uploadbutton").click(function () {
        var filename = $("#file").val();

        $.ajax({
            type: "POST",
            url: "addFile.do",
            enctype: 'multipart/form-data',
            data: {
                file: filename
            },
            success: function () {
                alert("Data Uploaded: ");
            }
        });
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

我没有上传文件,而是只得到文件名。我该怎么做才能解决此问题?


答案 1

使用HTML5,您可以使用Ajax和jQuery进行文件上传。不仅如此,您还可以执行文件验证(名称,大小和MIME类型)或使用HTML5进度标记(或div)处理进度事件。最近我不得不做一个文件上传器,但我不想使用Flash,也没有iframe或插件,经过一些研究,我想出了解决方案。

The HTML:

<form enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>
<progress></progress>

首先,如果需要,可以执行一些验证。例如,在文件的情况下:.on('change')

$(':file').on('change', function () {
  var file = this.files[0];

  if (file.size > 1024) {
    alert('max upload size is 1k');
  }

  // Also see .name, .type
});

现在,单击按钮即可提交:$.ajax()

$(':button').on('click', function () {
  $.ajax({
    // Your server script to process the upload
    url: 'upload.php',
    type: 'POST',

    // Form data
    data: new FormData($('form')[0]),

    // Tell jQuery not to process data or worry about content-type
    // You *must* include these options!
    cache: false,
    contentType: false,
    processData: false,

    // Custom XMLHttpRequest
    xhr: function () {
      var myXhr = $.ajaxSettings.xhr();
      if (myXhr.upload) {
        // For handling the progress of the upload
        myXhr.upload.addEventListener('progress', function (e) {
          if (e.lengthComputable) {
            $('progress').attr({
              value: e.loaded,
              max: e.total,
            });
          }
        }, false);
      }
      return myXhr;
    }
  });
});

如您所见,使用HTML5(和一些研究)文件上传不仅成为可能,而且非常容易。尝试使用Google Chrome,因为示例的某些HTML5组件并非在每个浏览器中都可用。


答案 2

2019年更新:这仍然取决于您的人口统计数据使用的浏览器。

使用“新”HTML5 API要了解的一件重要事情是,直到IE 10才支持它。如果您瞄准的特定市场对旧版Windows的倾向高于平均水平,则您可能无法访问它。file

截至2017年,大约5%的浏览器是IE 6,7,8或9之一。如果你进入一家大公司(例如,这是一个B2B工具或你为培训提供的东西),这个数字可能会飙升。2016年,我与一家在超过60%的机器上使用IE8的公司打交道。

截至本次编辑,现在是2019年,距离我最初的答案已经过去了近11年。IE9及更低版本在全球范围内约为1%大关,但仍有使用率较高的集群。

从中得出的重要结论是 - 无论功能如何 - 检查用户使用的浏览器。如果你不这样做,你会学到一个快速而痛苦的教训,为什么“为我工作”在可交付给客户的可交付成果中不够好。caniuse是一个有用的工具,但请注意他们从哪里获得人口统计数据。它们可能与你的不一致。这一点从未比企业环境更真实。

我2008年的回答如下。


但是,有一些可行的非JS文件上传方法。您可以在页面上创建一个 iframe(使用 CSS 隐藏该 iframe),然后将表单定位到该 iframe。主页不需要移动。

这是一个“真实”的帖子,所以它不完全是交互式的。如果你需要状态,你需要一些服务器端来处理它。这因服务器而异。ASP.NET 有更好的机制。PHP普通版失败了,但你可以使用Perl或Apache修改来解决这个问题。

如果您需要上传多个文件,最好一次上传一个文件(以克服最大文件上传限制)。将第一个表单发布到 iframe,使用上述内容监视其进度,并在完成后将第二个表单发布到 iframe,依此类推。

或者使用 Java/Flash 解决方案。他们在处理帖子时更加灵活...