通过input的onchange
事件获取到file对象,在通过file对象的slice
方法,类似于array
的slice
方法,将file对象分割成多个Blob
对象,每个Blob
对象都是一个单独的文件,可以通过ajax
上传到服务器,具体实现方法如下
<input type="file">
<script>
const input = document.querySelector('input')
input.onchange = () => {
const file = input.files[0] // 获取到的file对象
const fileList = handleFile(file, 60)
// ...对应的文件上传处理操作
}
// 将file对象处理成固定大小的文件的工具函数
const handleFile = (file, fileSize) => {
const result = []
for (let i = 0; i < file.size; i += fileSize) {
result.push(file.slice(i, i + fileSize))
}
return result
}
</script>
如果分片上传时被打断了(页面刷新,网络连接错误),如何知道哪一部分文件上传了,哪一部分文件没有上传?
利用hash算法,生成对应的hash值存储在数据库,上传文件的时候将当前文件的hash值与服务器返回的hash值进行比较,就能知道文件是否上传过,可以借助第三方库:spark-md5
<input type="file">
<script src="https://cdn.bootcdn.net/ajax/libs/spark-md5/3.0.2/spark-md5.js"></script>
<script>
const input = document.querySelector('input')
input.onchange = async () => {
const file = input.files[0] // 获取到的file对象
const fileList = handleFile(file, 60)
const result = await hash(fileList)
// ...对应的文件上传处理操作
}
// 生成hash值
const hash = (fileList = []) => {
return new Promise((resolve, reject) => { // 封装成异步函数
const spark = new SparkMD5()
const read = i => {
if (i >= fileList.length) {
resolve(spark.end())
return
}
const blob = fileList[i]
const reader = new FileReader()
reader.onload = e => {
const byte = e.target.result
spark.append(byte)
read(i + 1)
}
reader.readAsArrayBuffer(blob)
}
read(0)
})
}
// 将file对象处理成固定大小的文件的工具函数
const handleFile = (file, fileSize) => {
const result = []
for (let i = 0; i < file.size; i += fileSize) {
result.push(file.slice(i, i + fileSize))
}
return result
}
</script>