核心步骤
- 读取文件
- 按照指定大小将文件进行截取分割成多个内容
- file.slice(cur, cur + size) 这里处理后的内容是一个 Blob数据内容
- 将分割后的数据使用 formData 表单进行上传,使用Promise.all进行监控所有请求返回
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>大文件分片上传</title>
</head>
<body>
<input type="file" id="input" />
<button id="upload">上传</button>
</body>
</html>
<script>
let input = document.getElementById("input");
let upload = document.getElementById("upload");
let files = {};
const chunkList = []
const url = ''
input.addEventListener("change", (e) => {
files = e.target.files[0];
console.log('test files', files)
console.log('test files typeof', Object.prototype.toString.call(files))
createChunk(files)
console.log('test chunkList', chunkList)
});
function createChunk(file, size = 1 * 1024 * 1024) {
let cur = 0;
while (cur < file.size) {
chunkList.push({
file: file.slice(cur, cur + size)
})
return cur + size
}
}
async function uploadFile(list) {
const requestList = list
.map(({ file, fileName, index, chunkName }) => {
const formData = new FormData()
formData.append('file', file)
formData.append('fileName', fileName)
formData.append('chunkName', chunkName)
return { formData, index }
})
.map(({ formData, index }) => {
fetch(url, {
method: 'POST',
body: formData
}).then((res) => {
console.log(res);
})
})
await Promise.all(requestList)
}
upload.addEventListener('click', () => {
const uploadList = chunkList.map(({ file }, index) => ({
file,
fileName: files.name,
index,
chunkName: `${files.name}-${index}`,
size: file.size,
}));
uploadFile(uploadList);
})
</script>