最近在项目前端页面中需要上传文件,由于第三方插件弹出界面不符合要求以及可能会有安全隐患,准备采用html5的FileReader实现。
FileReader的兼容性目前已经很不错了,但在IE浏览器上会存在一个问题:不支持其中的readAsBinaryString方法,但支持readAsDataUrl方法。这个问题也容易解决,至少还不至于不能用。
html
<input type="file" accept=".rar,.zip,.gz" id="file">
js
var fileinfo = {name: '', size: 0, progress: 0, uploading: false};//结合vue.js使用效果更好
$('#file').on('change', function (e) {
var file = e.target.files[0];
var filesize = file.size; //文件大小,单位:Byte
var reader = new FileReader();
if (typeof FileReader != 'function') {
alert("您的浏览器不兼容当前页面,请改用Edge、360浏览器极速模式、火狐、Chrome等现代浏览器访问本页面");
}
if (typeof reader.readAsBinaryString == 'function') {
reader.readAsBinaryString(file);
} else if(typeof reader.readAsDataURL == 'function'){
reader.readAsDataURL(file);
}else{
alert("您的浏览器不兼容当前页面,请改用Edge、360浏览器极速模式、火狐、Chrome等现代浏览器访问本页面");
return;
}
reader.addEventListener('load', uploadFile(file));
}
function uploadFile(file){
if (typeof FormData != 'function') {
alert("您的浏览器不兼容当前页面,请改用Edge、360浏览器极速模式、火狐、Chrome等现代浏览器访问本页面");
}
var formData = new FormData();
formData.append('file', file);
$.ajax({
url: 'xxxxxx',
data: formData,
type: 'post',
dataType: 'json',
async: true, // 异步(true)时可能会收不到文件
processData: false, // 使数据不做处理
contentType: false, // 不设置Content-Type请求头
success: function (res) {
if (res && res.location) {
fileinfo.status = '上传成功';
fileinfo.uploading = false;
fileinfo.progress = 100;
fileinfo.location = res.location;
} else {
fileinfo.status = '上传失败:' + res.error;
}
},
error: function () {
fileinfo.status = '上传失败:服务器内部错误';
},
xhr: function () { //ajax请求前会先执行这段代码,绑定onprogress事件
var xhr = jQuery.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener("progress", function (e) {
if (e.lengthComputable) {
var percentComplete = e.loaded / e.total;
fileinfo.progress = Math.round(percentComplete); //调用此变量显示上传进度
}
}, false);
}
return xhr;
}
});
}