当前位置:网站首页>Implementation of large file fragment uploading based on webuploader
Implementation of large file fragment uploading based on webuploader
2022-06-22 05:37:00 【Best_ Kaka】
Preface
How to use vue-simple-uploader Realize the upload of fragments 、 Breakpoint retransmission and second retransmission ;
This study is based on WebUploader Implement these functions
Use
1. Introduce in the project webuploader
matters needing attention
1、 The plug-in is based on jquery,
2、 I won't support it npm Import ( adopt import './webuploader'; Way to introduce webuploader, Will be submitted to the ''caller', 'callee', and 'arguments' properties may not be accessed on strict mode ...' The fault of ,)
We are in the project index.html To statically import resources
stay Official website Upload and download
Uploader.swf and webuploader.min.js, Put it in static static Under the document

matters needing attention
In case of error report :Uncaught SyntaxError: Unexpected token ‘<‘,
yes vue Static resource import error :https://blog.csdn.net/weixin_43909743/article/details/118804322
- Encapsulate the upload component upload.vue
Packaged components upload.vue as follows , The interface can be expanded according to the specific business .
<template>
<div class="upload">
</div>
</template>
<script>
import {
getToken } from "@/utils/auth"; // headers What must be passed inside token
export default {
name: 'vue-upload',
props: {
accept: {
type: Object,
default: null,
},
// Upload address
url: {
type: String,
default: '',
},
// Maximum number of Uploads The default is 100
fileNumLimit: {
type: Number,
default: 100,
},
// Size limit Default 2M
fileSingleSizeLimit: {
type: Number,
default: 2048000,
},
// Parameters passed to the back end when uploading , It's usually token,key etc.
formData: {
type: Object,
default: null
},
// Generate formData The key, Here's just an example , Discuss with the back end about the specific form
keyGenerator: {
type: Function,
default(file) {
const currentTime = new Date().getTime();
const key = `${
currentTime}.${
file.name}`;
return key;
},
},
multiple: {
type: Boolean,
default: false,
},
// Upload button ID
uploadButton: {
type: String,
default: '',
},
},
data() {
return {
uploader: null
};
},
mounted() {
this.initWebUpload();
},
methods: {
initWebUpload() {
this.uploader = WebUploader.create({
auto: true, // After selecting the file , Whether to upload automatically
// swf: '/static/lib/webuploader/Uploader.swf', // swf File path It's not necessary
server: this.url, // File receiving server
pick: {
id: this.uploadButton, // Select the file button
multiple: this.multiple, // Upload multiple files or not Default false
label: '',
},
accept: this.getAccept(this.accept), // Allow selection of file format .
threads: 3,
fileNumLimit: this.fileNumLimit, // Limit the number of Uploads
//fileSingleSizeLimit: this.fileSingleSizeLimit, // Limit the size of a single uploaded image
formData: this.formData, // Upload the required parameters
chunked: true, // Patch uploading
chunkSize: 2048000, // Slice size
duplicate: true, // Repeat upload
headers: {
Authorization: "Bearer " + getToken() },
});
// When a file is added to the queue , Add to page preview
this.uploader.on('fileQueued', (file) => {
this.$emit('fileChange', file);
});
this.uploader.on('uploadStart', (file) => {
// You can be ready here formData The data of
//this.uploader.options.formData.key = this.keyGenerator(file);
});
// Create a progress bar to display in real time during file upload .
this.uploader.on('uploadProgress', (file, percentage) => {
this.$emit('progress', file, percentage);
});
this.uploader.on('uploadSuccess', (file, response) => {
this.$emit('success', file, response);
});
this.uploader.on('uploadError', (file, reason) => {
console.error(reason);
this.$emit('uploadError', file, reason);
});
this.uploader.on('error', (type) => {
let errorMessage = '';
if (type === 'F_EXCEED_SIZE') {
errorMessage = ` The file size cannot exceed ${
this.fileSingleSizeLimit / (1024 * 1000)}M`;
} else if (type === 'Q_EXCEED_NUM_LIMIT') {
errorMessage = ' The maximum number of file uploads has been reached ';
} else {
errorMessage = ` Upload error ! Please check and upload again ! Error code ${
type}`;
}
console.error(errorMessage);
this.$emit('error', errorMessage);
});
this.uploader.on('uploadComplete', (file, response) => {
this.$emit('complete', file, response);
});
},
upload(file) {
this.uploader.upload(file);
},
stop(file) {
this.uploader.stop(file);
},
// Cancel and interrupt file upload
cancelFile(file) {
this.uploader.cancelFile(file);
},
// Remove files from the queue
removeFile(file, bool) {
this.uploader.removeFile(file, bool);
},
getAccept(accept) {
switch (accept) {
case 'text':
return {
title: 'Texts',
exteensions: 'doc,docx,xls,xlsx,ppt,pptx,pdf,txt',
mimeTypes: '.doc,docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt'
};
break;
case 'video':
return {
title: 'Videos',
exteensions: 'mp4',
mimeTypes: '.mp4'
};
break;
case 'image':
return {
title: 'Images',
exteensions: 'gif,jpg,jpeg,bmp,png',
mimeTypes: '.gif,.jpg,.jpeg,.bmp,.png'
};
break;
default: return accept
}
},
},
};
</script>
<style lang="scss">
.webuploader-container {
position: relative;
}
.webuploader-element-invisible {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px,1px,1px,1px);
}
.webuploader-pick {
position: relative;
display: inline-block;
cursor: pointer;
background: #00b7ee;
padding: 10px 15px;
color: #fff;
text-align: center;
border-radius: 3px;
overflow: hidden;
}
.webuploader-pick-hover {
background: #00a2d4;
}
.webuploader-pick-disable {
opacity: 0.6;
pointer-events:none;
}
</style>
- Use components
<el-form-item v-show="form.struct == 'single'&&form.courseType == 2" label=" Video file ">
<div class="page">
<div id="filePicker"> Select File </div>
<div class="file-panel">
<div class="file-list">
<ul class="file-item" :class="`file-${file.id}`" v-for="file in fileList1" v-show="!form.videoUrl">
<li class="file-type" :icon="fileCategory(file.ext)"></li>
<li class="file-name">{
{
file.name}}</li>
<li class="file-size">{
{
fileSize(file.size)}}</li>
<li class="file-status"> Uploading ...</li>
<li class="progress"></li>
<li @click="remove1(file)"> close </li>
</ul>
<div class="no-file" v-if="!fileList1.length&&!form.videoUrl"><i class="iconfont icon-empty-file"></i> No files to upload </div>
<div class="no-file" v-if="form.videoUrl">
<i class="iconfont icon-empty-file"></i> {
{
form.videoUrl}}
<button @click="form.videoUrl=''"> Delete </button>
</div>
</div>
</div>
<vue-upload
:url="url1"
ref="uploader"
uploadButton="#filePicker"
@fileChange="fileChange"
@progress="onProgress"
@success="onSuccess"
></vue-upload>
</div>
</el-form-item>
data data
fileList1: [],
url1:process.env.VUE_APP_BASE_API + "/file?type=1",
computed: {
uploader() {
return this.$refs.uploader;
}
},
methods:
fileChange(file) {
if(this.fileList1.length){
return this.$message.warning(' Only one file can be uploaded at a time ')}
if (!file.size) return;
this.form.videoUrl=''
this.fileList1.push(file);
console.log(file);
},
onProgress(file, percent) {
$(`.file-${
file.id} .progress`).css('width', percent * 99 + '%');
$(`.file-${
file.id} .file-status`).html((percent * 99).toFixed(2) + '%');
},
onSuccess (file, response) {
console.log(' Upload successful ', response);
this.fileList1=[]
$(`.file-${
file.id} .file-status`).html( '100%');
this.form.videoUrl = response.data.url
},
resume(file) {
this.uploader.upload(file);
},
stop(file) {
this.uploader.stop(file);
},
remove1(file) {
// Cancel and interrupt file upload
this.uploader.cancelFile(file);
// Remove files from the queue
this.uploader.removeFile(file, true);
// stay ui Remove on
let index = this.fileList1.findIndex(ele => ele.id === file.id);
this.fileList1.splice(index, 1);
},
fileSize(size) {
return WebUploader.Base.formatSize(size);
},
fileCategory(ext) {
let type = '';
const typeMap = {
image: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp'],
video: ['mp4', 'm3u8', 'rmvb', 'avi', 'swf', '3gp', 'mkv', 'flv'],
text: ['doc', 'txt', 'docx', 'pages', 'epub', 'pdf', 'numbers', 'csv', 'xls', 'xlsx', 'keynote', 'ppt', 'pptx']
};
Object.keys(typeMap).forEach((_type) => {
const extensions = typeMap[_type];
if (extensions.indexOf(ext) > -1) {
type = _type
}
});
return type
},
css
<style lang="scss">
$h-row: 50px; .file-panel {
width: 100%;
margin-top: 10px;
box-shadow: 0 2px 12px 1px rgba(0, 0, 0, 0.1); > h2 {
height: 40px;
line-height: 40px;
padding: 0 10px;
border-radius: 4px 4px 0 0;
border-bottom: 1px solid #ccc;
background-color: #fff;
}
.file-list {
position: relative;
height: 100px;
overflow-y: auto;
background-color: rgb(250, 250, 250);
}
.file-item {
position: relative;
height: $h-row;
line-height: $h-row;
padding: 0 10px;
border-bottom: 1px solid #ccc;
background-color: #fff;
z-index: 1; > li {
display: inline-block;
}
}
.file-type {
width: 24px;
height: 24px;
vertical-align: -5px;
}
.file-name {
width: 40%;
margin-left: 10px;
}
.file-size {
width: 20%;
}
.file-status {
width: 20%;
}
.file-operate {
width: 10%; > a {
padding: 10px 5px;
cursor: pointer;
color: #666; &:hover {
color: #ff4081;
}
}
}
.file-type[icon=text] {
// background: url(../../assets/images/icon/text-icon.png);
}
.file-type[icon=video] {
// background: url(../../assets/images/icon/video-icon.png);
}
.file-type[icon=image] {
// background: url(../../assets/images/icon/image-icon.png);
}
.progress {
position: absolute;
top: 0;
left: 0;
height: $h-row - 1;
width: 0;
background-color: #E2EDFE;
z-index: -1;
}
.no-file {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 16px;
}
}
</style>
Result chart

Reference resources :
Back end reference :https://glory.blog.csdn.net/article/details/114284285
Reference link :https://www.jb51.net/article/136113.htm
边栏推荐
- From "platform transformation" to "DTC brand going to sea", what is the trend of 2021?
- Analysis of 43 cases of MATLAB neural network: Chapter 28 Application Research of decision tree classifier - breast cancer diagnosis
- innosetup判断程序已经运行方法
- 关于背包问题的总结
- A reminder to cross-border sellers who are still "shopping"!
- tmux -- ssh terminal can be closed without impact the server process
- C语言指针(进阶)
- 畢業回饋!Apache Doris 社區所有貢獻者來領禮品啦!
- Link a static library‘s all sections
- Remove then add string from variable of Makefile
猜你喜欢

【毕业季·进击的技术er】一个读研学生的唠唠嗑

2022 Shanxi secondary vocational group "Cyberspace Security" event module b- web page penetration

Analysis of 43 cases of MATLAB neural network: Chapter 28 Application Research of decision tree classifier - breast cancer diagnosis
![P1061 [NOIP2006 普及组] Jam 的计数法](/img/53/7ca41b2ed4084f49ebcc2dd47e5919.png)
P1061 [NOIP2006 普及组] Jam 的计数法

Analysis of 43 cases of MATLAB neural network: Chapter 29 research on the application of limit learning machine in regression fitting and classification -- Comparative Experiment

Kubernetes - deploy application to cluster
Wanzi detailed data warehouse, data lake, data middle platform and lake warehouse are integrated

Someone always asks me: how to play independent station? Three cases, you will understand after reading

在线文本代码对比工具

Kubernetes——使用minikube搭建环境
随机推荐
【云原生】2.2 kubeadm创建集群
Yarn application submission process
Opencv function usage details 1~10, including code examples
[cloud native] 2.2 kubeadm create cluster
[graduation season · advanced technology Er] a graduate student's chatter
Privatized lightweight continuous integration deployment scheme --05- continuous deployment service -drone (Part 1)
P1160 队列安排
Working method: 3C scheme design method
大厂晋升学习方法三:链式学习法
删除弹窗组件的封装使用
innosetup判断程序已经运行方法
QEMU ARM interrupt system architecture
redis连接错误:ERR Client sent AUTH, but no password is set解决方案2个
面对Google流量红利期,独立站卖家如何借势营销?
Some templates about bisection
Leetcode hot1-50
Kubernetes -- setting up an environment using minicube
tmux -- ssh terminal can be closed without impact the server process
TIDB-performance overview面板
Graduation feedback! All contributors of Apache Doris community come to receive gifts!