-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfile_slice.html
110 lines (105 loc) · 2.88 KB
/
file_slice.html
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="file" id="file" />
<script>
// 请求封装
// 1. http 并发 blob 上传 chunk / POST
// 2. 当blob Promise.All 再发送一个merge的请求 /merge
function request({
url,
method = 'POST',
data,
headers = {},
requestList // 上传的文件列表
}) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest(); // js ajax 对象
xhr.open(method, url); // 请求
Object.keys(headers).forEach(key =>
xhr.setRequestHeader(key, headers[key]) // 请求加头
);
xhr.send(data);
xhr.onload = e => {
resolve({
data: e.target.response
});
}
});
}
const mergeRequest = async () => {
await request({
url: 'http://localhost:3001/merge',
headers: {
"content-type": "application/json"
}
});
alert('上传成功');
}
document
.getElementById('file')
.addEventListener('change', async (event) => {
const file = event.target.files[0];
const file_name = file.name.split('.')[0];
// console.log(file);
// lastModified: 1644549553742
// lastModifiedDate: Fri Feb 11 20xx 11:19:13 GMT+0800 (中国标准时间) {}
// name: "banner.png"
// size: 138424
// type: "image/png"
// webkitRelativePath: ""
// console.log(Object.prototype.toString.call(file)); // [object File]
// console.log(file.slice(0, 102400)); // 100kb
// file.slice完成切片,blob类型文件切片,JS二进制文件类型的
// blob协议
// Blob {size: 102400, type: ''}
// size: 102400
// type: ""
let cur = 0, size = 0.5*1024*1024; // 1M
const fileChunkList = []; // blob数组
while(cur < file.size) {
fileChunkList.push({
// cur start offset end
file: file.slice(cur, cur + size)
});
cur += size;
}
// console.log(fileChunkList);
// 0:
// file: Blob {size: 1048576, type: ''}
// [[Prototype]]: Object
// 1:
// file: Blob {size: 1048576, type: ''}
// [[Prototype]]: Object
// 2: {file: Blob}
// 3: {file: Blob}
// length: 4
const requestList = fileChunkList
.map(({file}, index) =>{
const formData = new FormData(); // js post form
formData.append("chunk", file); // 二进制文件
formData.append("filename", `${file_name}-${index}`);
return {
formData
};
})
.map(async ({ formData}) => request({
// formData
url: 'http://localhost:3000', //前后端的api
data: formData
}))
await Promise.all(requestList); //并发吧....
// console.log(requestList)
await mergeRequest(); // 请求合并
// chunk: (binary)
// filename: 20210319003325-0
})
</script>
</body>
</html>