前端大文件分片上传

这篇具有很好参考价值的文章主要介绍了前端大文件分片上传。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.分片上传整体流程

  • 开始上传:前端启动文件分片上传。后端返回唯一标识。
  • 分片上传:获取到上传的文件,然后设置一个固定的分片大小,将文件切成多个小片,计算出每一个分片的MD5值(32位)。将每个分片的内容和MD5标识符一同上传至服务器。服务端接收每个分片及相关信息后,通过对每个分片进行校验,来确保分片的完整性。
  • 结束上传:当分片上传完毕或者前端取消上传时,调用结束上传接口结束此次文件上传操作。结束上传时,服务端判断是正常结束或取消上传来决定后续操作。

前端大文件分片上传,前端,javascript文章来源地址https://www.toymoban.com/news/detail-851846.html

2.前端具体流程

  • 开始上传,发送开始上传请求,向服务器传递文件名、文件总大小、分片总数和切片大小,获取并保存文件上传的唯一标识符。同时在发送请求前,对上传的文件名进行校验,如果文件名超过最大长度256,则禁止发送请求并向用户提示修改文件名称。
  • 分片上传,首先将文件进行切片,调用切片方法时,需要将文件传递给该方法,然后根据文件的大小来决定每个分片的大小并切分成多个片段,同时计算出总切片数,并为每个切片添加从0开始的顺序索引。随后对每个切片计算出他们的MD5值。最后把这些分片的MD5值和顺序索引保存在浏览器内存中。然后发送上传数据请求,向服务器发送唯一标识符、分片的顺序索引、分片数据,MD5值和当前分片的大小。在每个分片发送请求后,如果发送成功,则将其对应的信息从浏览器内存中删除,并计算出此时的上传进度,然后发送下一个片段直至最后。如果全部上传成功,清空浏览器内存。如果请求发生错误,则对该分片再次发送一次上传请求,如果仍然错误,不再上传,调用结束请求并提示错误原因。
  • 结束上传,如果文件分片全部成功上传,向服务器发送结束请求,传递正常结束状态码,清空浏览器内存。如果主动取消上传则传递取消请求状态码,同时清空浏览器内存,不再继续上传。

3.部分代码

//文件切片,utils

import SparkMD5 from 'spark-md5'

export async function getChunkList (files) {
	const file = files
	console.log(file);
	const fileSize = file.size // 文件大小
	const fileName = file.name

	let chunkSize = 0;
	if (fileSize <= 5 * 1024 * 1024) { // 0-5M,不分片
		chunkSize = fileSize;
	} else if (fileSize <= 20 * 1024 * 1024) { // 5-20M,每个分片大小1M
		chunkSize = 1024 * 1024;
	} else if (fileSize <= 50 * 1024 * 1024) { // 20-50M,每个分片大小2M
		chunkSize = 2 * 1024 * 1024;
	} else if (fileSize <= 100 * 1024 * 1024) { // 50-100M,每个分片大小4M
		chunkSize = 4 * 1024 * 1024;
	} else if (fileSize <= 200 * 1024 * 1024) { // 100-200M,每个分片大小6M
		chunkSize = 6 * 1024 * 1024;
	} else if (fileSize <= 500 * 1024 * 1024) { // 200-500M,每个分片大小10M
		chunkSize = 10 * 1024 * 1024;
	} else if (fileSize <= 1024 * 1024 * 1024) { // 500M-1G,每个分片大小20M
		chunkSize = 20 * 1024 * 1024;
	} else { // 1G以上,每个分片大小20M
		chunkSize = 20 * 1024 * 1024;
	}
	const totalChunks = Math.ceil(fileSize / chunkSize)
	let start = 0
	let end = Math.min(chunkSize, fileSize)
	let index = 0 // 分片索引,从0开始
	const chunks = [] // 存储当前文件的分片信息的数组

	while (start < fileSize) {
		const chunk = file.slice(start, end)
		const reader = new FileReader()
		const promise = new Promise((resolve, reject) => {
			reader.onload = (e) => { //读取文件分片信息,使用SparkMD5库计算分片的MD5值
				const spark = new SparkMD5.ArrayBuffer()
				spark.append(e.target.result)
				resolve(spark.end())
			}
			reader.onerror = (err) => {
				reject(err)
			}
		})
		reader.readAsArrayBuffer(chunk)
		try {
			const md5 = await promise
			const chunkInfo = { chunk, md5, index }
			chunks.push(chunkInfo)
		} catch (err) {
			reject(err)
		}
		//更新循环起止位置
		start = end
		end = Math.min(start + chunkSize, fileSize)
		index++
	}
	// 将当前文件的分片信息数组存入总的数组中
	return [chunks, totalChunks, fileSize, fileName, chunkSize] // 返回存储所有文件的分片信息的数组
} 	
async handleUpload () {
			this.progressState = 'upload'
			this.wrongNum = 0
			if (this.fileList.length == 0) { //判断是否添加文件
				this.$notify.warning({
					title: this.$global.warningMessage.title,
					message: this.$global.warningMessage.fileMessage,
				});
				return
			}
			if (this.file.name.length > 256) {
				this.$notify.warning({
					title: this.$global.warningMessage.title,
					message: this.$global.warningMessage.fileNameMessage,
				});
				return
			}
			this.totalSize = this.file.size
			// 调用getChunkList方法获取分片及相关信息
			const [chunks, totalChunks, fileSize, fileName, chunkSize] = await getChunkList(this.file.raw)
			this.totalChunks = totalChunks
			this.fileSize = fileSize
			this.fileName = fileName
			this.chunkList = chunks
			this.chunkSize = chunkSize
			console.log(this.chunkList);
			// 开始上传请求
			await this.startUpload()
			// 遍历分片信息数组,取出除文件分片外的其他信息
			const sessionChunkList = this.chunkList.map(({ chunk, ...rest }) => rest);
			// 将分片其他信息存入sessionStorage中
			sessionStorage.setItem("chunkData", JSON.stringify(sessionChunkList));
			let i = 0;
			while (i < this.chunkList.length && this.wrongNum < 1) { //对分片数组进行遍历
				const chunkInfo = this.chunkList[i];
				const res = await this.uploadChunk(chunkInfo); //调用上传分片方法
				if (res.data.state == 200) {
					const removeInfo = {
						md5: chunkInfo.md5,
						index: chunkInfo.index
					}
					await this.handleSuccess(removeInfo, chunkInfo) //调用当前分片上传成功处理函数
					i++;
				} else {   //上传未成功,重新上传一次
					const res = await this.uploadChunk(chunkInfo);
					this.wrongNum += 1
					if (res.data.state == 200) {
						this.wrongNum = 0
						await this.handleSuccess(removeInfo, chunkInfo)
						i++;
					} else {  // 重新上传一次后仍未成功
						const state = this.$global.completeUploadState.cancelUpload
						await this.completeUpload(state)
						this.$notify.error({
							title: this.$global.failedMessage.title,
							message: res.data.message
						});
						this.handleClear()
						return
					}
				}
			}
		}

到了这里,关于前端大文件分片上传的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端大文件分片上传 进度条展示 上传暂停、开始、取消

    实现的效果: 1、多个大文件(支持10个G以上)分片上传 2、进度条展示进度 3、控制文件上传暂停和取消 实现关键点: 1、文件预处理(md5计算、请求和进度处理等) 2、分片上传的流程(查询已上传分片、文件合并等) 3、文件的暂停、开始、取消 首先使用file类型的input框

    2024年04月26日
    浏览(37)
  • 【JS】前端分片上传大文件(支持1G以上的超大文件)

           如果将大文件一次性上传, 耗时会非常长,甚至可能传输失败 ,那么我们怎么解决这个问题呢?既然大文件上传不适合一次性上传,那么我们可以尝试将文件分片散上传。 这样的技术就叫做分片上传。分片上传就是将大文件分成一个个小文件(切片),将切片进行

    2024年04月11日
    浏览(48)
  • vue(前端):大文件分片上传(包括如何获取文件MD5、逻辑注释讲解)

    3.1 原生input标签实现上传 3.2 获取文件的MD5 3.3 上传文件 3.4 上传文件到后台

    2024年02月21日
    浏览(41)
  • node.js 前端直接分片上传文件与阿里云OSS的方法

    解决问题:直接由用户上传文件至阿里云OSS,而非经过中间件/后端 官方文档:分片上传 (aliyun.com)​​​​​​​​​​​ 在官方文档中,提供的方法是由中间件上传至oss,调用了path库,但是在浏览器用户没有那么大的权限,我们关注到文档中此表: 类型 参数 说明 必选参

    2024年02月11日
    浏览(53)
  • 前端 + 后端 实现分片上传(断点续传/极速秒传)

    先记录下,后面有时间再去实现 (已实现,可参考 SpringBoot+vue文件上传下载预览大文件分片上传文件上传进度 SpringBoot+vue 大文件分片下载) 可参考链接:vue上传大文件/视频前后端(java)代码 前端slice分片上传,后端用表记录分片索引和分片大小和分片总数,当接受完最后

    2023年04月17日
    浏览(47)
  • 如何使用阿里云OSS进行前端直传以及分片上传

    在使用阿里云OSS进行前端直传时,首先我们需要去阿里云官网注册自己的存储桶,然后申请相关的accessKeyId和accessKeySecret,然后新建一个桶,为这个桶命名以及选择对应的地区。 然后可以根据自己的业务,封装对应的组件,以下是根据我自己的项目,所封装的上传组件,所用

    2024年02月21日
    浏览(43)
  • SpringBoot+vue文件上传&下载&预览&大文件分片上传&文件上传进度

    SpringBoot+vue 大文件分片下载 Blob File spark-md5根据文件内容生成hash 大文件分片上传(批量并发,手动上传)vue组件封装-form组件 vue上传大文件/视频前后端(java)代码 springboot+vue自定义上传图片及视频 SpringBoot + VUE实现前台上传文件获取实时进度( 使用commons-fileupload设置上传监听

    2024年02月05日
    浏览(74)
  • gin分片上传文件

    这个为什么已经是老篇常谈了,主要的原因无非就是文件比较大,一次性上传如果网络中断等情况客户端又得重新上传,而且没法补充上传。 客户端: 有一个大文件,对这个文件进行切片,依据实际业务进行拆分,每一个文件片说白了就是一个[]byte 保证文件的一致性: 需要对每

    2024年02月09日
    浏览(46)
  • Minio文件分片上传实现

    资源准备 MacM1Pro 安装Parallels19.1.0请参考 https://blog.csdn.net/qq_41594280/article/details/135420241 MacM1Pro Parallels安装CentOS7.9请参考 https://blog.csdn.net/qq_41594280/article/details/135420461 部署Minio和整合SpringBoot请参考 https://blog.csdn.net/qq_41594280/article/details/135613722 Minio Paralles虚拟机文件百度网盘获取

    2024年01月21日
    浏览(41)
  • Java实现文件分片上传

    Java实现文件分片上传 为什么要使用分片上传 在需要上传文件时,不可避免地会遇到上传文件内容过大,上传时间太长地问题,采用文件分片上传就可以解决这个问题。 什么是分片上传? 简单的说就是本来是需要一次搬一个很大的东西,比如是一大桶水,一次搬起来比较费

    2024年02月08日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包