在前端开发中,文件上传是一个常见需求。然而,由于浏览器对 AJAX 的支持差异较大,造成了在处理文件上传时需要兼容多种浏览器的问题。本文将介绍如何使用纯 JavaScript 实现异步文件上传,并兼容 IE8+。
前置知识
在开始学习本文内容之前,你需要掌握以下知识:
- HTML
- JavaScript
- XMLHttpRequest 对象
准备工作
在 HTML 中添加一个表单,用于上传文件:
<form id="uploadForm" method="post" enctype="multipart/form-data"> <input type="file" name="file"> <button type="submit">上传</button> </form>
在 JavaScript 中,我们需要为表单的提交事件添加监听器,阻止默认行为,然后自己处理文件上传:
var uploadForm = document.getElementById('uploadForm'); uploadForm.addEventListener('submit', function(e) { e.preventDefault(); // 处理文件上传 });
文件上传
在处理文件上传时,我们需要用到 XMLHttpRequest
对象。该对象可以实现异步文件上传。
首先,我们需要创建一个 XMLHttpRequest
对象:
var xhr = new XMLHttpRequest();
然后,我们需要注册 xhr.upload
对象的事件,在文件上传过程中获取上传进度:
xhr.upload.addEventListener('progress', function(e) { if (e.lengthComputable) { var percentage = Math.round(e.loaded / e.total * 100) + '%'; console.log('上传进度:' + percentage); } });
接下来,我们需要为 xhr
对象设置请求的 URL、请求方法和是否异步:
xhr.open('POST', '/upload', true);
然后,我们需要创建一个 FormData
对象,将表单数据(包括文件)添加到其中:
var formData = new FormData(uploadForm);
最后,我们调用 xhr.send()
方法发送请求:
xhr.send(formData);
完整的代码如下所示:
-- -------------------- ---- ------- ------------------------------------- ----------- - ------------------- --- --- - --- ----------------- --------------------------------------- ----------- - -- -------------------- - --- ---------- - ------------------- - ------- - ---- - ---- ------------------- - ------------ - --- ---------------- ---------- ------ --- -------- - --- --------------------- ------------------- ---展开代码
兼容 IE8+
在 IE8 中,由于不支持 FormData
和 XMLHttpRequest.upload
对象,因此不能直接使用上述代码。
为了解决这个问题,我们可以使用 iframe 来实现文件上传。具体方法如下:
首先,在 HTML 中添加一个隐藏的 iframe:
<iframe id="uploadTarget" name="uploadTarget" style="display: none;"></iframe>
然后,在 JavaScript 中,我们需要修改表单的 target
属性,将其指向该 iframe:
uploadForm.target = 'uploadTarget';
接下来,我们需要为 iframe 设置 load
事件的监听器,在文件上传成功后获取服务器返回的数据:
var uploadTarget = document.getElementById('uploadTarget'); uploadTarget.addEventListener('load', function() { var responseText = uploadTarget.contentDocument.body.innerText; console.log('服务器返回数据:' + responseText); });
最后,在表单提交之前,我们需要将表单的 enctype
属性修改为 "multipart/form-data"
,并将其 encoding
属性修改为 "multipart/form-data"
:
var enctype = uploadForm.getAttribute('enctype'); uploadForm.setAttribute('enctype', 'multipart/form-data'); var encoding = uploadForm.getAttribute('encoding'); uploadForm.setAttribute('encoding', 'multipart/form-data');
完整的代码如下所示:
-- -------------------- ---- ------- ------------------------------------- ----------- - ------------------- --- ------------ - ---------------------------------------- ------------------------------------- ---------- - --- ------------ - ------------ - ---------------------------------------------------------- -------- --------------------------------------------------------------------------------展开代码