< JavaScript技术分享: 大文件切片上传 及 断点续传思路 >

news2024/12/23 22:42:41

在这里插入图片描述

文章目录

  • 👉 前言及含义
      • 切片上传
      • 断点续传
  • 👉 一、实现思路
  • 👉 二、使用场景
  • 👉 参考文献
  • 👉 伸手党福利: 即拿即用(前/后端思路均有)
  • 往期内容 💨


👉 前言及含义

在开发过程中,不管怎样简单的需求,在量级达到一定层次时,都会变得异常复杂。

就拿今天要说的文件上传来说,文件上传简单,但是当文件大小变得太大超出控制时,就会变得复杂了!

当上传大文件时,会存在以下几个变量会影响我们的用户体验

  1. 服务器处理数据的能力
  2. 上传时间会变长,高频次文件上传失败,失败后又需要重新上传等等
  3. 当遇到网络波动时,大文件上传容错率下降
  4. 上传文件请求超时

为了解决上述问题,我们需要对大文件上传单独处理

这里涉及到切片上传断点续传两个概念

切片上传

顾名思义,切片上传,就是将所要上传的大文件,按照一定的大小,将整个文件切割成多个数据块(Part)来进行分片上传。上传完之后再由服务端对所有上传的文件进行汇总整合成原始的文件。

大致流程如下

  1. 将需要上传的文件按照一定的分割规则,分割成相同大小的数据块;
  2. 初始化一个分片上传任务,返回本次分片上传唯一标识;
  3. 按照一定的策略(串行或并行)发送各个分片数据块;
  4. 发送完成后,服务端根据判断数据上传是否完整,如果完整,则进行数据块合成得到原始文件

断点续传

断点续传,指的是在下载或上传时,将下载或上传任务人为的划分为几个部分

每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载。用户可以节省时间,提高速度。现在常用的网盘下载工具和云存储平台大多采用了这种方式,可由用户手动暂停或继续文件上传、下载等操作。

一般实现方式有两种

  1. 服务器端返回,告知从哪开始
  2. 浏览器端自行处理

上传过程中将文件在服务器写为临时文件,等全部写完了(文件上传完),将此临时文件重命名为正式文件即可

如果中途上传中断过,下次上传的时候根据当前临时文件大小,作为在客户端读取文件的偏移量,从此位置继续读取文件数据块,上传到服务器从此偏移量继续写入文件即可。不过反复中断,小概率导致文件合并后,数据乱码的情况出现。

👉 一、实现思路

  1. 拿到文件,对文件进行fingerprint = md5(file),得到文件指纹。
  2. 将唯一标识指纹保存服务器。
  3. 切割文件,分段上传,每次上传一段。
  4. 服务器根据指纹进行索引判断文件上传进度,直到文件的全部片段上传完毕。

切片上传思路图
下面的内容都是伪代码(仅提供思路参考)
1. 读取文件内容:

// <input type="file" name="XXX" id="XXX" />
const input = document.querySelector('input')
input.addEventListener('change', function() {
    var file = this.files[0]
});

2. 可以使用md5, 实现文件的唯一性加密

const md5Code = md5(file)

3. 将文件进行切割,分成若干“块”小文件

// 创建一个reader对象, 允许操作file或blob
var reader = new FileReader()
// 用于启动读取指定的 Blob 或 File 内容
reader.readAsArrayBuffer(file)
// 当文件成功读取时,执行load 事件
reader.addEventListener("load", (e) => {
	//每10M切割一段,这里只做一个切割演示,实际切割需要根据实际文件大小,指定循环切割的片数和每片的大小...
	var slice = e.target.result.slice(0, 10*1024*1024)
});

FileReader相关理论知识 (点击跳转)

4.将切片逐片上传

const formData = new FormData();
// 与后端协商,看看如何界定上传片数。
// 如上面流程图所述,可以在第一片(尽量切小片一点,降低出错率)上传的时候,携带这个大文件对应的信息,如:整体裁切片数,文件总大小,文件名称及文件类型等等
//这里是有一个坑的,部分设备无法获取文件名称和文件类型,可以通过读取文件二进制流,解析文件类型,具体可以通过百度了解,不展开叙述。主要讲思路
formData.append('file-' + index, slice) // index 代表 此片的序号
formData.append('fileName', file.filename)
formData.append('fileType', file.fileType)
formData.append('md5Code', md5Code)

// 》XMLHttp
var xhr = new XMLHttpRequest()
xhr.addEventListener('load', function() {
    //xhr.responseText
})
xhr.open('POST', '')
xhr.send(formData)
// 监听
xhr.addEventListener('progress', updateProgress)
xhr.upload.addEventListener('progress', updateProgress)

function updateProgress(event) {
    if (event.lengthComputable) {
        //进度条
    }
}

// 》 ajax
$.ajax({
	type:"post",
	url:"http://XXXXX",
	async:true,
	data:formData,
	cache:false,
	processData: false,
	contentType: false,
	xhr: function xhr() {
		//获取原生的xhr对象
		var xhr = $.ajaxSettings.xhr();
		if (xhr.upload) {
			//添加 progress 事件监听
			xhr.upload.addEventListener('progress', function (e) {
				//e.loaded 已上传文件字节数
				//e.total 文件总字节数
				var percentage = parseInt(e.loaded / e.total * 100)
			}, false)
		}
		return xhr
	},
	success:function(res){
		alert(JSON.stringify(res))
	}
})

// 》 axios
let config = {
	headers:{
		'Content-Type':'multipart/form-data',
	},
	transformRequest: [function (data) {
		return data
	}],
	onUploadProgress: progressEvent => {
		//上传进度百分比
		let persent = (progressEvent.loaded / progressEvent.total * 100 | 0)
		console.log(persent)
	},
}
axios.post(
	'http://xxxxxxxx/video/upload',
	formData,
	config
).then(response=>{
	var result = response.data
	if(result.status == 0){
		console.log(result)
	}else{
		this.$message({
			message: '上传失败',
			type: 'error',
			duration:'1000'
		})
	}
}).catch(err => {
	console.log(err)
})

说明:e.loaded 为已上传文件字节数,e.total 为文件总字节数,可通过计算得出已上传字节数占比,读者可根据自己项目需要使用进度条或进度环

有了切割上传后,也就有了文件唯一标识信息,断点续传变成了后台的一个小小的逻辑判断

后端主要做的内容为:根据前端传给后台的md5值,到服务器磁盘查找是否有之前未完成的文件合并信息(也就是未完成的半成品文件切片),取到之后根据上传切片的数量,通过接口返回,告诉前端开始从第几节上传,继续进行上次未完成的文件上传

如果想要暂停切片的上传,可以使用XMLHttpRequest 的 abort 方法,其他请求同样有对应的暂停方法,可百度了解。

👉 二、使用场景

  • 大文件加速上传:当文件大小超过预期大小时,使用分片上传可实现并行上传多个 Part, 以加快上传速度
  • 网络环境较差:建议使用分片上传。当出现上传失败的时候,仅需重传失败的Part。而不会导致因网络问题,不断重新上传整个文件,提高容错率。
  • 流式上传:可以在需要上传的文件大小还不确定的情况下开始上传。这种场景在视频监控等行业应用中比较常见

👉 参考文献

js实现文件切片上传,断点续传
百度冲浪

👉 伸手党福利: 即拿即用(前/后端思路均有)

提供自掘金大佬:前端切片上传文件(可暂停),以链接形式返回

往期内容 💨

🔥 < 每日技巧: JavaScript代码优化 >

🔥 < 每日知识点:关于Javascript 精进小妙招 ( Js技巧 ) >

🔥 <Javascript技巧: Javascript 是个难泡的妞,学点技巧征服 “ 她 ” >

🔥 < 在element-ui中: 使用el-tree + el-table组件,联动请求用户数据表格组件 (基础版,后续可能更新) >

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/138758.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MVVM学习

mvvm基础知识Model&#xff1a;repository Entity 数据库 网络访问等对数据进行直接操作的代码View:视图代码 xml activity fragment adapter 等ui层的一些代码ViewModel:视图模型 用来和View ,Model层交互&#xff0c;将Model层的数据显示到View上&#xff0c;并处理View层的事…

Android Softap Mac地址随机化

目录 Android Q以后 Android Q 获取方式 Android Q以后 在SoftapManager创建的时候,可以跟下 Android Q Q:WifiManager#getWifiApConfiguration()只能获取到SSID和pwd等,无法获取到对应的BSSID。 原因分析:Android Q Softap的MAC地址设置是在HAL层,并没有给Framework赋…

result.isAck()报错

IDEA 的 bug&#xff0c;两张图解释

图像平滑处理

平滑处理是指在某些数学和统计分析中&#xff0c;对于原始数据做出拟合&#xff0c;并生成更平滑的数据。这通常是为了抑制原始数据中的离群点或噪声&#xff0c;使得数据更具可读性和可解释性。 在图像处理中常用于模糊处理和降低噪声。平滑滤波器使用给定邻域内的像素平均灰度…

Word处理控件Aspose.Words功能演示:在 C# .NET 中将 Word 转换为 PDF - 完整指南

Aspose.Words 是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c; Aspose API支持流行文件格式处…

JS面试题--JavaScript基础

1. new操作符的实现原理 创建一个对象将构造函数的作用域赋给新对象&#xff08;也就是将对象的__proto__属性指向构造函数的prototype属性&#xff09;指向构造函数中的代码&#xff0c;构造函数中的this指向该对象&#xff08;也就是为这个对象添加属性和方法&#xff09;返…

Arthas tt -t , tt -i 以及 watch相关使用理解 解析入参和结果等

Arthas tt 系列作用 方法执行数据的时空隧道&#xff0c;记录下指定方法每次调用的入参和返回信息&#xff0c;并能对这些不同的时间下调用进行观测 一、 tt -t 作用和一般用法 tt -t 一般用于监控某一个方法的调用记录&#xff0c;如果调用多此会出现多条记录&#xff0c;一…

怎么申请icp备案?怎么查询icp备案是否申请成功

什么是icp备案号&#xff1f; 简单来说&#xff0c;icp备案号&#xff0c;就是你网站的备案号码。icp备案号就是当你的网站提交备案资料&#xff0c;经工业信息化产业部&#xff08;及各地通信管理局&#xff09;审核通过后&#xff0c;会通过电子邮箱发送一个备案号码给你…

JVM内存结构及内存溢出OOM

JVM内存结构JVM的内存结构大致分为五个部分&#xff0c;分别是程序计数器、虚拟机栈、本地方法栈、堆和方法区。除此之外&#xff0c;还有由堆中引用的JVM外的直接内存。下面将展开讲解这五个部分。程序计数器程序计数器(Program Counter Register)&#xff0c;用于记录下一条J…

券商接口关闭的情况下怎么做到实时量化买入?通达信破解接口可以吗?

现在券商接口关闭的情况下怎么做到实时量化买入&#xff1f;量化买入有一些第三方软件是可以破解券商接口的。像通达信破解接口它有一个什么机构版还是什么&#xff0c;他可以同时几个券商一起买入&#xff0c;当然这个你需要用手工输入。像其他的像一些A计划&#xff0c;它就是…

【 java 集合】List接口常用实现类对比以及ArrayList和LinkedList源码分析

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

绿控传动冲刺科创板上市:连年亏损,现金流紧张,计划募资11亿元

近日&#xff0c;苏州绿控传动科技股份有限公司&#xff08;下称“绿控传动”&#xff09;在上海证券交易所递交招股书&#xff0c;准备在科创板上市。 本次冲刺上市&#xff0c;绿控传动计划募资10.72亿元&#xff0c;其中7.16亿元用于年产新能源商用车电驱动系统10万套项目&a…

泛微特色政务应用:对内协同办公、对外高效服务,推动政务数字化

近年来&#xff0c;国家不断深入建设“数字化政府”&#xff0c;政务服务“网上办”、“掌上办”、“一网通办”已经成为政务服务新方向。 泛微数字化运营平台为各级政府机关、行政事业单位&#xff0c;打造覆盖各级市、区、县、乡镇街道、村及各级社区部门的网上协同办公平台…

Qt编译CTK

文章目录一、CTK简介二、CTK下载三、CTK编译一、CTK简介 CTK是什么 CTK 为支持生物医学图像计算的公共开发包&#xff0c;其全称为 Common Toolkit CTK 提供了什么 当前&#xff0c;CTK 工作的主要范围包括&#xff1a; DICOM&#xff1a;提供了从 PACS 和本地数据库中查询和…

基础数据结构——链表

目录 一、链表 1、数组的缺点 2、链表 3、单向链表 4、双向链表 5、Python链表的实现 二、例题 一、链表 1、数组的缺点 1&#xff09;需要占用连续的空间 若某个数组很大&#xff0c;可能没有这么大的连续空间给它用。 2&#xff09;不方便删除和插入 例如删除数组…

MySQL如何查看未提交的事务SQL

点击上方蓝字关注我MySQL中经常遇到事务中的SQL正在执行或执行完成后未提交&#xff0c;如何找出对应的SQL&#xff1f;1. 查看正在执行的SQL查看事务中正在执行的SQL方式有多种&#xff0c;例如1.1 通过processlist查看会话1&#xff1a;执行1个SQLmysql> begin; Query OK…

AC7811-BLDC无感控制代码调试与测试记录

接线注意 供电 对于 AC781x 电机 Demo 板&#xff0c;其 MCU 控制板和功率板的 12V 输入只需接一路即可&#xff0c;如果电机额定电压为 12V&#xff0c;那么将功率板中的功率管供电模式选择跳点(靠近 D5)短接即可&#xff0c;不需要再额外供电&#xff1b;如果电机的额定电压…

配置磁盘多路径聚合

一 安装多路径软件 yum install -y device-mapper device-mapper-multipath 二 配置多路径聚合 在每个节点上都需要配置下多路径聚合。 /* 注意事项&#xff1a; 新添加盘后要扫描下&#xff0c;才能识别到(如果已经看到盘了&#xff0c;即执行multipath -ll能看到&#…

《收获,不止Oracle》读书笔记之性能提升千倍

体系学习让SQL语句性能提升千倍 未优化前&#xff0c;单车速度 drop table t purge; create table t(x int);create or replace procedure proc1 as beginfor i in 1..100000loopexecute immediateinsert into t values (||i||);commit;end loop; end; / /*这里要记得预先执行…

linux下常用调试技巧

1 linux下如何查看静态库和动态库都链接了那些库 1.1 静态库.a是没有指令可以看到其在生成过程中链接了那些库的 1.2 动态库.so可以通过ldd指令查看其在生成过程中链接了那些库 还有一种简单直观的方法,我们可以在编译过程中看到所生成的二进制文件,链接了那些库: 平时编译…