大文件分片上传
# 大文件的分片上传
# 文件的hash值代表文件的唯一性
- 任何数据->hash值
- 安装
spark-md5
(增量算法):算出各块的hash,防止内存增爆
const inp = document.querySelector('input')
const precent = 0
inp.onchange = async (e) => {
// 获取file对象
const file = e.targert.files[0]
if(!file) {
return
}
// ------------------------------------------
// 多文件上传
if(e.target.files.length > 1) {
fileList.value.concat(e.target.files)
} else {
fileList.value.push(e.target.files[0])
}
// ----------------------------------------------
// 切片为blob对象(10MB)
const piece = file.slice(0, 100) // 0-99个字节
const chunks = createChunks(file, 10 * 1024 *1024)
// 计算hash
const result = await hash(chunks)
}
// 计算文件的hash
function hash(chunks) {
return new Promise((resolve, reject) => {
const spark = new SparkMD5()
function _read(i) {
if(i >= chunks.length) {
const hash = spark.end()
console.log('hash', hash)
resolve(hash)
return // 读取完成
}
const blob = chunks[i]
const reader = new FileReader()
// 因为是异步的转化,所以需要在onload获取reader的结果
reader.onload = (e) => {
const bytes = e.target.result // 读取到的字节数组
spark.append(bytes)
_read(++i)
}
reader.onerror = (error) => {
reject(error)
}
reader.readAsArrayBuffer(blob)
}
_read(0)
})
}
// 切片函数
function createChunks(file, chunkSize) {
const result = []
for (let i = 0;i < file.size; i+=chunkSize) {
result.push(file.slice(i, i + chunkSize))
}
return result
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# formData发送数据给后端
- 需要设置请求头
header:Content-Type: multipart/form-data
async submit () {
// 多文件上传
fileList.value.forEach((item) => {
let _fromData = new FormData()
_formData.append("user", "asdasd")
_formData.append(item.name + "file", file) // file对象
axios.post('/xxx', _formData)
})
// 切片上传进度条
const size = 2 * 1024 *1024
const current = 0
while(current < file.size) {
let _fromData = new FormData()
_fromData.append(file.name, file.slice(current, current + size))
precent = Math.min((current / file.size) * 100, 100)
current += size
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
编辑 (opens new window)