如何在没有jQuery的情况下异步上传文件并支持IE6-9?

时间:2017-10-31 03:52:31

标签: javascript asynchronous file-upload internet-explorer-6

我有一个简单的表单来上传同步运行良好的文件:

<form id="uploadForm" action="/upload" method="post" encType="multipart/form-data">
  <input type="file" id="file" name="file" accept=".csv" />
  <input type="text" name="comment" />
  <button type="submit">Upload</button>
</form>

如何让这个表单异步上传文件(不重新加载页面?),并在上传完成时收到通知,如果有任何错误?

我知道发出异步请求的主要方法是使用XMLHttpRequest,我发现现在可以使用以下内容(我没有测试过这段代码):

function handleLoad() {
  console.log(this.responseText);
}
function handleError(error) {
  console.error(error.stack);
}
function handleSubmit(e) {
  e.preventDefault();
  var form = document.getElementById('uploadForm');
  var request = new XMLHttpRequest();
  request.addEventListener('load', handleLoad);
  request.addEventListener('error', handleError);
  request.open("POST", "/upload");
  request.send(new FormData(form));
}

但是according to MDN,仅在IE10 +中支持发送FormDataBlobFileArrayBuffer,我想要向后兼容的解决方案(不使用jQuery)。

How can I upload files asynchronously?有很多答案,但到目前为止我读过的所有答案都使用jQuery或使用我上面描述的现代XMLHttpRequest方法。

我正在使用React,并且对jQuery提供的任何其他内容都没有用处,所以我想通过使用vanilla JS来解决这个问题,让我的页面下载量更小。

1 个答案:

答案 0 :(得分:-1)

最早建立的方法是将<form>目标设为隐藏<iframe> 元素,方法是将target="<name of iframe>"添加到<form>元素。当您在JavaScript中调用form.submit()时,它会在目标<iframe>中加载响应:

<form id="uploadForm" action="/upload" method="post" encType="multipart/form-data" target="asyncFrame">
  <iframe id="asyncFrame" name="asyncFrame" height="0" width="0" frameborder="0"></iframe>
  <input type="file" id="file" name="file" accept=".csv" />
  <input type="text" name="comment" />
  <button type="submit">Upload</button>
</form>

<script>
  var iframe = document.getElementById('asyncFrame');

  function handleLoad() {
    console.log('response:', iframe.contentWindow.document.body.innerText);
  }
  iframe.addEventListener('load', handleLoad);
</script>

这种方法最尴尬的是无法获取响应的状态代码,并且没有标准方式(据我所知)来确定请求是否失败。您必须检查响应正文(iframe.contentWindow.document.body.innerText)以确定是否存在错误(如果您要发布到自己的服务器,幸运的是,您可以确保响应正文包含足够的信息,但如果它是第三方服务器,你可能运气不好。)