前端分片上传
需求描述: 前端获取文件md5码且实现分片上传
步骤:
一:获取文件md5
1.插件spark-md5,还有另外一个插件(browser-md5-file)但是不兼容ie11,至于其他ie版本,未测
2.以分片的方式获取文件MD5码,一下为封装的方法:
/**
* @param file 文件
* @param chunkSize 分片大小
* @returns Promise
*/
const getFileMd5 = (file, chunkSize) => {
return new Promise((resolve, reject) => {
setSpin({
spinning: true,
tip: '正在努力导入应用数据,请耐心等待......',
});
let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
let chunks = Math.ceil(file.size / chunkSize); // 总分片数
let currentChunk = 0;
let spark = new SparkMD5.ArrayBuffer();
let fileReader = new FileReader();
fileReader.onload = function(e) {
spark.append(e.target.result);
currentChunk++;
if (currentChunk < chunks) {
loadNext();
} else {
let md5 = spark.end(); // 结束时调用
resolve(md5);
}
};
fileReader.onerror = function(e) {
reject(e);
};
// 文件分片
function loadNext() {
let start = currentChunk * chunkSize;
let end = start + chunkSize;
if (end > file.size) {
end = file.size;
}
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
}
loadNext();
});
}
二、文件分片调取接口
/**
*
* @param {Object} file 文件
* @param {Number} index 下标
* @param {Number} chunkSize 分片数
* @param {String} md5 md5码
*/
const fileImport = (file, index, chunkSize, md5) => { // 获取MD5
const chunks = Math.ceil(file.size / chunkSize); // 防止文件截取不完整 所以向上取整
if (file) {
let upSize = index * chunkSize;
if (index > chunks - 1) {
return;
}
let blob = file.slice(upSize, upSize + chunkSize); // 截取文件
try {
let formData = new FormData();
formData.append('file', blob);
formData.append('md5', md5);
formData.append('chunk', index);
formData.append('chunks', chunks);
sliceImportVisualization(formData).then(async res => {
if (res?.isSuccess) {
await fileImport(file, ++index, chunkSize, md5); // 在上一片传输完成后再调用 切记 切记
const { data = {} } = res;
const { file_name } = data;
if (file_name) {
importVisualization({ file_name }).then(res => {
setSpin({spinning: false});
});
}
}
});
} catch (err) {
console.log('分片上传错误...', err);
}
}
};