大文件切片上传处理

上传js文件

import axios from "axios";
import SparkMD5 from "spark-md5";
//正常上传
const upload = (url, data, headers = {}) => {
return new Promise((resolve, reject) => {
axios({
url,
method: "post",
data,
headers: {
...headers,
"Content-Type": "multipart/form-data",
},
})
.then((res) => {
return resolve(res.data);
})
.catch((err) => {
return reject(err);
});
});
};
//分片上传
const uploadByPieces = async (url, { fileName, file }) => {
// 变量
const chunkSize = 5 * 1024 * 1024; // 5MB一片
const chunkCount = Math.ceil(file.size / chunkSize); // 总片数
const fileMd5 = await getFileMd5(file);
// 获取当前chunk
const getChunkInfo = (file, index) => {
let start = index * chunkSize;
let end = Math.min(file.size, start + chunkSize);
let chunk = file.slice(start, end);
return { start, end, chunk };
};
// 分片上传
const uploadChunk = (data) => {
return new Promise((resolve, reject) => {
axios({
url,
method: "post",
data,
headers: {
"Content-Type": "multipart/form-data",
},
})
.then((res) => {
return resolve(res.data);
})
.catch((err) => {
return reject(err);
});
});
};
// 单个chunk上传
const readChunk = async (index) => {
const { chunk } = getChunkInfo(file, index);
let fetchForm = new FormData();
const chunkMd5 = await getFileMd5(chunk);
// chunkNumber(索引编号) index
// identifier(md5)
// chunkSize(块大小) chunkSize
// currentChunkSize(当前块大小) chunk.size
// totalSize(总大小) file.size
// totalChunks(块总数) chunkCount
// fileName(MD5-索引) identifier-index
// type(csv) csv
// file(文件块) chunk
fetchForm.append("chunkNumber", index);
fetchForm.append("identifier", fileMd5);
fetchForm.append("chunkSize", chunkSize);
fetchForm.append("currentChunkSize", chunk.size);
fetchForm.append("totalSize", file.size);
fetchForm.append("totalChunks", chunkCount);
fetchForm.append("fileName", chunkMd5 + "-" + index);
fetchForm.append("type", "csv");
fetchForm.append("file", chunk);
// 打印切片内容
// for (var item of fetchForm.entries()) {
// console.log(item[0] + ", " + item[1]);
// }
// console.log("-----------------------");
// return;
return uploadChunk(fetchForm);
};
// 针对每个文件进行chunk处理
const promiseList = [];
try {
for (let index = 0; index < chunkCount; ++index) {
promiseList.push(readChunk(index));
}
const res = await Promise.all(promiseList);
return { res, fileMd5 };
} catch (e) {
return e;
}
};
/**
* 获取文件MD5
* @param file
* @returns {Promise<unknown>}
*/
function getFileMd5(file) {
let fileReader = new FileReader();
fileReader.readAsBinaryString(file);
let spark = new SparkMD5();
return new Promise((resolve) => {
fileReader.onload = (e) => {
spark.appendBinary(e.target.result);
resolve(spark.end() + Date.now());
};
});
}
export { upload, uploadByPieces, getFileMd5 };

调用上传方法

beforeFileUpload(file) {
if (file.size < 5 * 1024 * 1024) {
this.commonUpload();
} else {
this.piecesUpload(file);
}
return false;
},
// 分片上传
async piecesUpload(file, isVerifiableSource = false) {
let url = "/api/xxxxx";
let data = {
file,
fileName: file.name,
};
const loading =
this.$eleUtils.openFullScreenLoading("该文件较大,请耐心等待...");
const res = await uploadByPieces(url, data);
loading.close();
console.log(res);
// 调用合并文件接口
this.mergeFile(file, res.fileMd5, isVerifiableSource);
},

html代码

<el-upload
action=""
accept=".csv"
:multiple="false"
:limit="1"
:show-file-list="false"
:before-upload="beforeFileUpload"
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">提示</div>
</el-upload>
posted @   Li_pk  阅读(124)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程
点击右上角即可分享
微信分享提示