最近在写一个需求,是批量上传视频到oss,然后自动匹配表格每一项对应的视频地址,,踩了不少坑,用antd的demo来上传oss,发现是全部一次性提交,如果文件小是没有问题的,但是一个文件上百M,同时上传几十个文件会导致上传失败率很高,所以试了很多个网上的demo,踩了不少坑,后来看了下阿里云直接上传文件的样式,有了一个想法,限制下同时上传的个数,比如上传20个,同时上传的个数为3,完成一个再走下一个,这样就会依次去掉接口,不会因为时间太长,导致接口失败。
需求图,通过上传的视频名称和题目名称自动匹配填充到视频地址字段,或者单个视频上传添加
首先是用的antd-Upload手动上传的UI,
render() {
const { fileList,uploadList,onceObj } = this.state;
const { text, index,multiple } = this.props;
const props = {
onRemove: file => {
this.setState(state => {
const index = state.fileList.indexOf(file);
const newFileList = state.fileList.slice();
newFileList.splice(index, 1);
return {
fileList: newFileList,
};
});
},
beforeUpload: file => {
this.setState(state => ({
fileList: [...state.fileList, file],
}));
return false;
},
fileList,
showUploadList: false,
accept: "video/*",
multiple: multiple,
};
return (
<div className="uploadVideoWrap">
<Upload {...props}>
<Button type="primary" icon={<UploadOutlined />}>上传</Button>
</Upload>
</div>
);
}
然后是获取上传文件的进度,这里是使用的ajax请求的接口
$.ajax({
url : url,
type : 'POST',
enctype: 'multipart/form-data',
data : formData,
// 告诉jQuery不要去处理发送的数据
processData : false,
// 告诉jQuery不要去设置Content-Type请求头
contentType : false,
timeout : 60000000,//设置超时时间
beforeSend:function(){
console.log("现在开始上传文件!");
},
xhr: function(){
let myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',function(e) {
if (e.lengthComputable) {
let { uploadList } = _this.state;
let percent = Math.floor((e.loaded/e.total)*100);//这里是上传的进度
//处理逻辑,设置进度条值
}
},false);
myXhr.upload.addEventListener('load',function(e) {
console.log('fish')
},false);
}
return myXhr;
},
success : function(res) {
console.log(res)
},
error : function(res) {
}
});
其他的就是处理逻辑了,完整代码如下
import React, {
Component} from 'react';
import {
Upload, Button, message, Progress} from 'antd';
import {
UploadOutlined } from '@ant-design/icons';
import {
getOssPolicy} from "@/api/common";
import $ from "jquery";
import '@/styles/components/uploadVideoAjax.scss'
class uploadVideoAjax extends Component {
state = {
fileList: [],
count: 0,
uploadList: [],
timer: null,
onceObj: {
}
};
// 开始上传,限制同时上传的个数,this.state.count限制上传的次数
handleUpload = () => {
const {
fileList } = this.state;
if(this.state.count>2 || fileList.length===0){
// 文件上传完毕
return
}
const formData = new FormData();
fileList.forEach(file => {
formData.append('files[]', file);
});
let files = fileList.splice(0,1)
this.setState({
fileList
})
this