theme: mk-cute highlight: atelier-lakeside-light
WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。采用大文件分片并发上传,极大的提高了文件上传效率。
Web Uploader下载命令:npm install webuploader
依赖: jquery下载老版本:^1.12.0
1.创建dom结构
<div class="uploader">
<co-button type="info" id="picker"></co-button>
<co-button id="ctlBtn" type="success">上传到服务器</co-button>
</div>
2.初始化WebUploader
设置上传文件的一些基础配置
let uploader = WebUploader.create({
pick: {
id: '#picker', // 指定选择文件的按钮
innerHTML: '选择文件' // 设置按钮文案
},
accept: {
extensions: 'zip', // 可接受上传的文件类型
mimeTypes: '.zip', // mime类型
},
// 上传所需请求参数
formData: {
chunkSize: 50 * 1024 * 1024, // 分片大小(50MB)lp
},
swf: 'http://cdn.staticfile.org/webuploader/0.1.0/Uploader.swf', // swf文件路径
server: `${window.markEnv.backend_url}/api/mark/file/upload`, // 请求路径
disableGlobalDnd: true, // 是否禁掉整个页面的拖拽功能
auto: false, // 是否有文件选择即开始上传
chunked: true, // 是否要分片处理大文件上传
threads: 6, // 并发量
timeout: 0, // 超时时间
})
3.在uploader实例化之前注入Hook
- 生成MD5之后开始切片并上传到服务端
- 这里需要服务端配合返回对应的状态码,判断本次上传的文件状态
WebUploader.Uploader.register(
{
name: 'contractUpload',
'before-send-file': 'beforeSendFile', // 在文件发送之前request,此时还没有分片
'before-send': 'beforeSend', // 在分片发送之前request,可以用来做分片验证
},
{
beforeSendFile: function (file) {
// Deferred对象在钩子回掉函数中经常要用到,用来处理需要等待的异步操作。
let task = new $.Deferred()
// 根据文件内容来查询MD5
uploader
.md5File(file)
.progress(function (percentage) {
// 显示进度
if (that.tableData[0])
this.tableData[0].md5Loading = Number(
(percentage * 100).toFixed(1)
)
})
.then(function (val) {
// 完成
file.md5 = val
// 开始上传切边
Ajax.post('/api/mark/file/check', {
md5: file.md5,
dataType,
})
.then((data) => {
let status = data.code
task.resolve()
switch (status) {
case 200:
// 正常流程
that.$message.success(data.msg)
break
case 100:
// 忽略上传过程,直接标识上传成功;
that.$message.warning(data.msg)
that.tableData[0].state = data.msg.split('!')[0]
uploader.reset()
uploader.skipFile(file)
file.pass = true
break
case 102:
// 部分已经上传到服务器了,但是差几个模块。
that.$message.warning(data.msg)
file.missChunks = data.data
break
case 103:
// 表示正在解压
that.$message.warning(data.msg)
that.tableData[0].state = data.msg.split('!')[0]
uploader.reset()
uploader.skipFile(file)
file.pass = true
break
case 500:
that.$message.error(data.msg)
uploader.reset()
break
default:
break
}
})
.catch((err) => {
that.$message.error(err.msg + '')
that.isLoading = false
uploader.reset()
})
})
return $.when(task)
},
)
4.监听上传状态
// 当有文件被添加进队列的时候
uploader.on("fileQueued", function (file) {
this.tableData.unshift({
name: file.name.split(".")[0],
size: (file.size / 1024 / 1024).toFixed(2) + "(MB)",
type: file.ext,
time: "———",
state: "等待上传中",
md5Loading: 0,
allLoading: 0,
});
});
// 当某个文件的分块在发送前触发,主要用来询问是否要添加附带参数
// 大文件在开起分片上传的前提下此事件可能会触发多次
uploader.onUploadBeforeSend = function (obj, data) {
let file = obj.file;
data.md5 = file.md5 || "";
data.uid = file.uid;
};
// 上传中
uploader.on("uploadProgress", function (file, percentage) {
let time = new Date();
this.tableData[0].state = "上传中";
this.tableData[0].time = time.toLocaleString();
this.tableData[0].allLoading = Number((percentage * 100).toFixed(1));
});
// 上传成功返回结果
uploader.on("uploadSuccess", function (file) {
this.tableData[0].state = "上传完成";
this.isLoading = false;
uploader.reset();
});
// 上传失败返回结果
uploader.on("uploadError", function (file) {
this.isLoading = false;
this.tableData[0].state = "上传失败";
this.$message.error("上传失败,请稍后重试!");
uploader.reset();
});
5.组件销毁之前清除注册事件
如果不对当前组件进行处理,当其它组件再次使用时,beforeSendFile会调用上一次缓存的记录
WebUploader.Uploader.unRegister("contractUpload");