文件上傳是很多項目中用到的功能,最近項目要實現文件上傳下載,分片上傳、斷點續傳、異步導出、同步導出等功能,所以去研究研究以下該內容,並將學習到的知識彙總寫出來分享一下,以我自己的理解寫出來。
文件上傳的實現常見的有以下幾種:
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檢查、分片上傳、斷點續傳,前後端代碼及原理圖。
以儘量追求詳細、通俗易懂。