首页 > 其他分享 >js 大文件切片,中止上传,上传进度,断点续传

js 大文件切片,中止上传,上传进度,断点续传

时间:2023-10-21 14:01:03浏览次数:22  
标签:断点续传 const await js 切片 file 服务器 上传

大文件切片上传
背景介绍:当涉及大文件上传时,一种有效的方法是将大文件分割成小切片并逐个上传。这种技术不仅可以减轻服务器的负担,还可以避免上传过程中的中断和内存问题。本文将介绍如何使用JavaScript实现大文件切片上传,并解释如何处理断点续传、并发控制以及上传取消等问题,用到的知识点有大文件切片、中止上传 、上传进度、断点续传、并发数量控制。

切片上传原理
大文件切片上传的基本原理是将文件分成多个固定大小的小切片,然后逐个上传到服务器。服务器收到这些切片后,可以按顺序合并它们,还原为完整的文件。这种方法不仅能提高上传效率,还能应对网络波动和服务器性能限制。

实现步骤
下面是实现大文件切片上传的基本步骤:

切片生成: 使用JavaScript将大文件切割成小切片,可以使用File API中的File.slice()方法。

切片上传: 将切片逐个上传到服务器,可以使用XMLHttpRequest或Fetch API发送切片数据。

服务器处理: 服务器接收并保存切片,并记录每个切片的索引。

切片合并: 当所有切片上传完成后,服务器按照索引顺序合并切片(或者后端提供合并接口将hash值传给后端进行合并),还原为完整文件。

断点续传
通过记录已上传切片的索引,即使上传过程中断,也可以从断点处继续上传。服务器只需判断已存在的切片,避免重新上传。

并发控制
为了避免同时上传大量切片导致网络拥塞,可以控制并发上传数。例如,一次最多只上传3个切片,等待其中一个完成后再上传下一个。

上传取消
允许用户在上传过程中取消操作是很重要的。为此,可以使用一个标记来判断是否取消上传,如果取消,则终止上传过程。

接下来,我们将深入探讨如何在JavaScript中实现这些功能。从切片生成和上传开始,逐步讲解如何处理断点续传、并发控制和上传取消。

话不多说,上代码
<template>
<div class="manage">
<input type="file" @change="handleFileChange" multiple />
<button @click="stop">停止上传</button>
<span>当前已上传:{{progress}}%</span>
</div>
</template>

<script>
export default {
name: 'Menu',
props: {
},
mounted () {
},
data () {
return {
progress: 0,
stopUpload: false,
totalChunks: null,
selectedFiles: [],
uploadPromises: [],
concurrentLimit: 2 // 控制并发数量
}
},
methods: {
handleFileChange (event) {
this.selectedFiles = Array.from(event.target.files)
this.startUpload(event.target.files)
},
async uploadFile (file, index, total) {
return new Promise((resolve, reject) => {
// 模拟上传操作,实际上传操作可能需要使用 XMLHttpRequest 或其他上传库
// setTimeout(async () => {
// console.log(`Uploaded: ${file.name}`)
// const formData = new FormData();
// formData.append('fileChunk', file);
// formData.append('chunkIndex', index);
// formData.append('totalChunks', total);
// const response = await fetch('upload-url', {
// method: 'POST',
// body: formData
// });
// const result = await response.json();
// resolve(result)
// }, 1000) // 假设上传耗时 1 秒
setTimeout(async () => {
console.log(`Uploaded: ${file.name}`)
resolve()
}, 2000) // 假设上传耗时 1 秒
})
},
async startUpload (file) {
console.log('file', file)
this.uploadPromises = []
const size = 1024 * 1024
const formNum = Math.ceil(file[0].size / size)
const hashes = []
for (let i = 0; i <= formNum; i++) {
const start = size * i;
const end = size * (i + 1)
const chunk = file[0].slice(start, end);
const hash = await this.calculateHash(chunk);
console.log('this.stopUpload', this.stopUpload)
if (this.stopUpload) return false
hashes.push(hash)
// 将需要上传的切片和对应的哈希值添加到FormData中
// 断点续传逻辑需要后端判断,前端根据片段生成唯一hash值,后端存储hash,续传时候需要判断若已上传直接给出进度
const promise = this.uploadFile(chunk, i, formNum)
this.uploadPromises.push(promise)

if (this.uploadPromises.length >= this.concurrentLimit) {
await Promise.race(this.uploadPromises) // 控制并发
this.uploadPromises.shift() // 移除已完成的 Promise
}
this.progress = (i / formNum) * 100
}
console.log('hashes', hashes)
await Promise.all(this.uploadPromises) // 等待剩余的上传完成
console.log('全部完成上传!')
// 调用后端提供合并接口
// const response = await fetch('upload-merge', {
// method: 'POST',
// body: hashes
// })
},
async calculateHash (chunk) {
const buffer = await chunk.arrayBuffer()
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer)
const hashArray = Array.from(new Uint8Array(hashBuffer))
const hashHex = hashArray.map(byte => byte.toString(16).padStart(2, '0')).join('')
return hashHex
},
stop () {
this.stopUpload = true
}
}
}
</script>



参考文章:http://blog.ncmem.com/wordpress/2023/10/21/js-%e5%a4%a7%e6%96%87%e4%bb%b6%e5%88%87%e7%89%87%ef%bc%8c%e4%b8%ad%e6%ad%a2%e4%b8%8a%e4%bc%a0%ef%bc%8c%e4%b8%8a%e4%bc%a0%e8%bf%9b%e5%ba%a6%ef%bc%8c%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0/

欢迎入群一起讨论

 

 

标签:断点续传,const,await,js,切片,file,服务器,上传
From: https://www.cnblogs.com/songsu/p/17778879.html

相关文章

  • java项目实践-jsp-finter-监听器-day19
    目录1.jsp2.过滤器3.listener监听器1.jspservle逻辑处理方便html页面表现麻烦jsp页面表现方便但是逻辑处理麻烦JSP是一种页面技术JSP本质上是servlet类通过JSP引擎翻译成servletjsp约等于java+html注意:jsp不是访问静态的html文件index.jsp修改成如下代码:<%-......
  • json序列化数据超出最大值(maxJsonLength)
    https://www.cnblogs.com/ellafive/p/13704301.html 1、序列化:以下代码在对象过大时会报错:进行序列化或反序列化时出错。字符串的长度超过了为maxJsonLength属性设置的值。//jsonObj比较大的时候会报错varserializer=newJavaScriptSerializer();returnserializer.Ser......
  • The JSON value of length n is too large and not supported
    https://github.com/dotnet/runtime/issues/39953 I'mreferringtothisissue #30746 thatwasclosedwithlimitof125MBstayingfixedopposedtobeingconfigurable.Itwasarguedthattherewouldbenocommoncaseshittingthe125MBlimit.Suchcases......
  • 使用.Net6中的System.Text.Json遇到几个常见问题及解决方案
    前言以前.NetCore是不内置JSON库的,所以大家都用Newtonsoft的JSON库,而且也确实挺好用的,不过既然官方出了标准库,那更方便更值得我们多用用,至少不用每次都nuget安装Newtonsoft.Json库了。不过日常开发使用中会有一些问题,本文记录一下解决方法,欢迎交流~字符编码问题默认的 System......
  • thinkPHP5.0返回的接口返回 json数据,用了json_encode不生效,却返回的却是text/html格
    如何让返回的数据完全是json1、用SoapUI来测试借口,Content-Type不是json,而是text/html;2、自己的接口,最后的数据用了json_encode,也是不管用的;3、用header来设置Content-Type也没有效果;4、而改框架的配置default_return_type为json,这也是不可取的,整站是网站需要返回的还是te......
  • 基于Vue.js和Spring Boot的口罩自助售卖系统:设计、实现与技术深度解析
    本文介绍了一种基于Vue.js和SpringBoot的口罩自助售卖系统的设计与实现。该系统通过前端Vue.js框架和后端SpringBoot框架的结合,实现了用户注册登录、口罩浏览购买、订单管理等功能。通过详细的代码示例和技术深度的解析,读者能够全面了解系统的设计思路和实现方法。1.引言随着全......
  • MySql Json字段部分查询语法
    模糊匹配jsonObject字段select*fromtableNamewherecolumnName->'$.xx'like'%xx%'精确匹配jsonObject类型字段select*fromtableNamewherecolumnName->'$.xx'='xx'模糊匹配jsonArray字段select*fromtableNamewh......
  • 详解vue大文件视频切片上传的处理方法
    前端上传大文件、视频的时候会出现超时、过大、很慢等情况,为了解决这一问题,跟后端配合做了一个切片的功能,接下来就详细的给大家介绍一下vue大文件视频切片上传的处理方法,需要的朋友可以参考下 前端上传大文件、视频的时候会出现超时、过大、很慢等情况,为了解决这一问题,跟......
  • markdown上传csdn调整插入图片大小及位置
    @目录前言1csdn插入图片1.1<img不显示图片?不能使用?2csdn带尺寸的图片3csdn移动图片位置并且带尺寸前言关于markdown上传csdn无法显示本地图片的问题请看我的另一篇文章【2023最新教程】解决markdown上传csdn无法显示本地图片的问题本文章讲叙了自己在markdown上传cs......
  • 上传超大文件到云端服务器
    一直以来,通过互联网传送超大文件都是个麻烦事,传统的SSH/FTP工具只适合传输不太大的文件和目录,遇到上G的文件经常会出现传输错误,常用手段如百度云在Linux服务器上没法使用,一些专业传输软件需要在服务端安装开端口,而我们日常遇到的超大文件越来越多,linux的安装包要几个G,docker镜像要......