文件上传是很多项目中用到的功能,最近项目要实现文件上传下载,分片上传、断点续传、异步导出、同步导出等功能,所以去研究研究以下该内容,并将学习到的知识汇总写出来分享一下,以我自己的理解写出来。
文件上传的实现常见的有以下几种:
1、基于aioxs和jquery的上传;
2、基于element-ui中的uploader的上传;
3、基于webuploader的上传。
前两种基本相同,element-ui有ui样式,其最终的上传还是利用到aioxs和jquery的。1和2的优点是简单,缺点是对大文件的上传、网络故障重新上传没有支持,需要自己去实现,工作量较大,在往后的文章中会介绍基于两者的断点续传、分片上传的实现。webuploader是百度的一个文件上传框架,js的支持,ui样式需要自己去添加实现,其可以叫轻松实现断点续传、分片上传的功能。断点续传、分片上传的应用场合是大文件上传。而小文件的上传利用element-ui实现较轻量级,其ui也支持拖拽上传、头像上传、缩略图等。
下面分别大概介绍下这三者的一些基础理解:
1、基于aioxs和jquery的上传
代码如下:
<template>
<div class="hello">
<input class="file" name="file" type="file" accept="image/png, image/gif, image/jpeg" @change="update" />
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: String
},
methods: {
update(e) {
let file = e.target.files[0];
alert(file.name);
console.log(file);
let param = new FormData(); //创建form对象
param.append("file", file); //通过append向form对象添加数据
console.log(param.get("file")); //FormData私有类对象,访问不到,可以通过get判断值是否传进去
let config = {
headers: { "Content-Type": "multipart/form-data" }
}; //添加请求头
this.$http
.post("http://127.0.0.1:8081/data/up", param, config)
.then(response => {
console.log(response.data);
}).catch(
error=>{
alert("失败");
}
);
}
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
</style>
2、基于element-ui中的uploader的上传
实现的效果:
<el-upload
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:limit="3"
:on-exceed="handleExceed"
:file-list="fileList">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
<script>
export default {
data() {
return {
fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}]
};
},
methods: {
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
},
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${ file.name }?`);
}
}
}
</script>
这里的代码只是选中文件,然后展示出来,并没有发送请求到服务端,所有需要添加基于aioxs和jquery的上传,将data中的filelist发送到服务端。
element-ui官网
3、基于webuploader的上传
html部分
<div id="uploader" class="wu-example">
<!--用来存放文件信息-->
<div id="thelist" class="uploader-list"></div>
<div class="btns">
<div id="picker">选择文件</div>
<button id="ctlBtn" class="btn btn-default">开始上传</button>
</div>
</div>
创建webuploader对象,配置对象参数。
var uploader = WebUploader.create({
// swf文件路径
swf: BASE_URL + '/js/Uploader.swf',
// 文件接收服务端。
server: 'http://webuploader.duapp.com/server/fileupload.php',
// 选择文件的按钮。可选。
// 内部根据当前运行是创建,可能是input元素,也可能是flash.
pick: '#picker',
// 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
resize: false
});
// 当有文件被添加进队列的时候
uploader.on( 'fileQueued', function( file ) {
$list.append( '<div id="' + file.id + '" class="item">' +
'<h4 class="info">' + file.name + '</h4>' +
'<p class="state">等待上传...</p>' +
'</div>' );
});
// 文件上传过程中创建进度条实时显示。
uploader.on( 'uploadProgress', function( file, percentage ) {
var $li = $( '#'+file.id ),
$percent = $li.find('.progress .progress-bar');
// 避免重复创建
if ( !$percent.length ) {
$percent = $('<div class="progress progress-striped active">' +
'<div class="progress-bar" role="progressbar" style="width: 0%">' +
'</div>' +
'</div>').appendTo( $li ).find('.progress-bar');
}
$li.find('p.state').text('上传中');
$percent.css( 'width', percentage * 100 + '%' );
});
文件上传失败会派送uploadError事件,成功则派送uploadSuccess事件。不管成功或者失败,在文件上传完后都会触发uploadComplete事件。
uploader.on( 'uploadSuccess', function( file ) {
$( '#'+file.id ).find('p.state').text('已上传');
});
uploader.on( 'uploadError', function( file ) {
$( '#'+file.id ).find('p.state').text('上传出错');
});
uploader.on( 'uploadComplete', function( file ) {
$( '#'+file.id ).find('.progress').fadeOut();
});
最重要的是在创建webuploader对象时没有设置自动上传时需要触发上传,设置了自动上传就不需要设置触发。
触发上传的api
uploader.upload();
以上时webuploader的基本使用,它还包括:
md5文件检查校验:对md5文件相同的可以跳过不上传,避免相同文件的上传。
分片上传、断点续传的支持。关于这些内容会在往后的文章中给出。
webuploader官网
这里只是概述性的描述文件上传的内容,提供一个思路,后面会一一给出具体的实现代码及原理说明等。
往后的内容包括:
1、原生的非组件的实现分片上传及断点续传,前后端代码及原理图;
2、基于webuploader的MD5检查、分片上传、断点续传,前后端代码及原理图。
以尽量追求详细、通俗易懂。