1. 首页
  2. >
  3. 前端开发
  4. >
  5. HTML5

WebUploader之单个大文件分片上传(前端实现)

1、组件简介

webuploader(官方定义):是一个以 HTML5 为主, Flash为辅的文件上传组件,采用大文件分片/并发上传的方式,极大地提高了文件上传的效率,同时兼容多种浏览器版本;

链接: WebUploader官网.

2、前端代码实现

首先,下载组件,并引入到项目文件;

t/wealth_nana/article/details/105051649

WebUploader之单个大文件分片上传(前端实现)

本例子模拟后台所需参数:


WebUploader之单个大文件分片上传(前端实现)

话不多说,直接上代码。

//引入组件
import WebUploader from "webuploader";
let uploader = null,GUID = null;

onReady(){
GUID = WebUploader.Base.guid();//每个文件有自己唯一的guid
uploader = WebUploader.create({
//设置选完文件后是否自动上传
auto: false,
//swf文件路径
// swf: 'vendor/webUpload/Uploader.swf',
// 文件接收服务端。
server: "http://www.baidu.com/BigFileUpload", //服务器端的上传页面地址
// 选择文件的按钮。可选。
// 内部根据当前运行是创建,可能是input元素,也可能是flash.
pick: "#fileupload",//点击选择文件的按钮id
chunked: true, //开启分块上传
chunkSize: 10 * 1024 * 1024,//10M 一个分片
chunkRetry: 3, //网络问题上传失败后重试次数
threads: 1, //上传并发数
//fileNumLimit :1,
fileSizeLimit: 1000 * 1024 * 1024, //最大1GB
fileSingleSizeLimit: 1000 * 1024 * 1024,
resize: false,//不压缩
formData: {},
//选择文件类型
accept: {
title: 'Zip files',
extensions: 'zip',
mimeTypes: '.zip'
},
});

// 当有文件被添加进队列的时候
uploader.on("fileQueued", function (file) {
//进行是否采用分片上传判断
if(file.size > 50*1024*1024){
uploader.option.chunked = true;
}else{ //文件的大小 小于 50M 则不采用分片上传
uploader.option.chunked = false;
}

//md5计算
uploader
.md5File(file)
.progress(function (percentage) {
// console.log("Percentage:", percentage);
})
// MD5计算完毕,可以点击上传了
.then(function (fileMd5) {
// 完成
file.wholeMd5 = fileMd5; //获取到了md5
});
});

// 文件上传过程中创建进度条实时显示。
uploader.on("uploadProgress", function (file, percentage) {
if (percentage * 100 > 100) {
return;
}
dialogUploadVm.progress = parseInt(percentage * 100);
});

// 当validate不通过时,会以派送错误事件的形式通知调用者。
uploader.on("error", function (type) {
if (type == 'Q_EXCEED_SIZE_LIMIT') {
notification.error({
message: '上传的文件大小不能超过1GB',
title: '通知'
});
}else if(type == 'Q_TYPE_DENIED') {//当文件类型不满足时触发
notification.error({
message: '仅支持上传zip压缩文件',
title: '通知'
});
}
});

//发送前填充数据,主要用来询问是否要添加附带参数
uploader.on("uploadBeforeSend", function (block, data) {
// block为分块数据。
console.log(block);
console.log(data);

// file为分块对应的file对象。
var file = block.file;
var fileMd5 = file.wholeMd5;

// 修改data可以控制发送哪些携带数据。
// 将存在file对象中的md5数据携带发送过去。

data.chunk = block.chunk;
data.chunks = block.chunks;
data.md5Value = fileMd5; //md5,文件的MD5值
data.id = file.id;//文件ID
data.fileName = file.name;//文件名称
// data.file = file;//当前所传分片
data.guid = GUID;
data.type = 0;

// 删除其他数据(默认的上传字段)
delete data.lastModifiedDate;
delete data.size;
delete data.name;
});

//当文件上传成功时触发。
uploader.on("uploadSuccess", function (file, response) {
//response {Object}服务端返回的数据
if (response.code == 1602) {
notification.error({
message: '上传失败,已存在最新版本的文件',
title: '通知'
});
} else if (response.code == 0) {
//success
} else {
notification.warn({
message: response.msg,
title: '通知'
});
setTimeout(() => {
dialogUploadVm.progress = 0;
}, 1500);
}
});

//当文件上传出错时触发。
uploader.on("uploadError", function (file, reason) {
//reason {String}出错的code
notification.error({
message: "上传出错,请重新上传",
title: '通知'
});
});

//上传完成后回调
uploader.on("uploadComplete", function (file) {
uploader.reset();//重置uploader。目前只重置了队列。
});

//上传完后的回调方法
uploader.on("uploadFinished", function () {
//提交表单
uploader.reset();//重置uploader。目前只重置了队列。
});
}

//确定上传的时候执行此函数:
function okButton(){
//假设拿到了需要额外上传的内容,比如 版本号,版本信息
let inputJson = {
"version": "",
"updateInfo": "",
};

uploader.options.formData = {//这里可以设置组件外需要上传的参数
"type": 0,//与组件内部type参数冲突,若要使用需在 uploadBeforeSend 时修改 data.type;
"version": this.inputJson.version,
"changeLog": this.inputJson.updateInfo,
};
uploader.upload(); //上传
}3、注意点
根据条件判断 是否采用分片上传 功能的代码需写在 “文件被添加进队列的时候”,即 fileQueued;如果在 “uploadBeforeSend” 时进行判断会无效。
在 uploadBeforeSend 时进行组件相关参数赋值,不需要的组件默认自带参数用 delete 删除。
设置组件外需要上传的参数,用 uploader.options.formData 进行赋值。
选择文件后可能会无法再次选择文件,需要 uploader.reset(); 重置一下队列。
————————————————
版权声明:本文为CSDN博主「wealth_nana」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wealth_nana/article/details/105051649

3、注意点

根据条件判断 是否采用分片上传 功能的代码需写在 “文件被添加进队列的时候”,即 fileQueued;如果在 “uploadBeforeSend” 时进行判断会无效。

在 uploadBeforeSend 时进行组件相关参数赋值,不需要的组件默认自带参数用 delete 删除。

设置组件外需要上传的参数,用 uploader.options.formData 进行赋值。

选择文件后可能会无法再次选择文件,需要 uploader.reset(); 重置一下队列。

4、传参情况

WebUploader之单个大文件分片上传(前端实现)

5、目前遇到的一个坑

点击按钮不会出现弹框

模拟官方文档上传按钮,但是发现怎么点击都没反应,但是当按下 F12 时就可以点击。其实是WebUploader初始化的时候,封装了一个 input 标签,属性 type=‘file’。初始化的时候因为获取不到正确的自身或者容器的大小,这时候初始化出来的这个透明层的大小为 1px*1px,根本点不到,也就触发不了点击事件,只需要在css里面加上一段代码:

WebUploader之单个大文件分片上传(前端实现)

#fileupload div:nth-child(2){
width:100%!important;
height:100%!important;
}