大文件分片上传前端手写

此前介绍过,文件上传前端有造好的轮子可以方便使用,比如百度fex的webuploader。那么我们离开这些轮子,自己手写一个难不难呢?完成基本功能确实不难,但是要把方方面面的情况都考虑到,那可就不简单了。我们先从简单的做起吧。
首先是分片,html的file类型input元素可以从本地选择文件,js里可以识别为一个Blob对象,它的方法slice(start, end)可以返回一个新的Blob对象,我们可以把Blob对象添加到formdata里,post到服务器以完成分片上传的功能。前端和后端要统一约定分片大小,比如5MB字节?各分片的start,end分别是[0,5M],[5M,10M],最后一个分片也许不足5M,那么end参数需要设置为准确的值么,比如size?实际上并不需要,仍然按start,start+5M,分片blob并不会把实际不足的部分填充,传到服务器上仍然是不足5MB的最后一片。

//const chunkSize = 1024 * 1024 *5
function  uploadchunk(index,gfile){
	let formData = new FormData()
	formData.append("name", gfile.name)
	formData.append("idx", index)
	formData.append("file", gfile.slice(index * chunkSize, (index+1) * chunkSize))
	axios.post("/upload", formData).then(res => { document.getElementById("uploadprogress").value=(++total)*100/Math.ceil(gfile.size/chunkSize); });
	}

页面里弄了一个文件上传的进度条,可以根据完成上传分片数不断更新进度。
大文件分片会很多,当然不要一下子并发将所有分片上传,这样前端会先挂掉,那么并发限制为多少合适呢?建议不要超过CPU核数,window.navigator.hardwareConcurrency,可以取这个参数值或者它的一半也行。
借鉴asyncpool的写法,可以把限制并发数的上传功能这样来编写:

//const poolLimit=window.navigator.hardwareConcurrency
//const chunkSize = 1024 * 1024 *5
function upload() {
	let ufile=document.getElementById("btnfile").files[0];
	total=0

	axios.post("/createfile",{name:ufile.name}).then(res => {
		(async () => {
			const ret = [];
			const executing = [];
			let chunksum=Math.ceil(ufile.size/chunkSize)
			for (let i=0;i<chunksum;i++) {
				const p = Promise.resolve().then(() => uploadchunk(i,ufile));
				ret.push(p);
				if ( poolLimit<= chunksum) {
					const e = p.then(() => executing.splice(executing.indexOf(e), 1));
					executing.push(e);
					if (executing.length >= poolLimit) { await Promise.race(executing); }
					}
				}
			await Promise.all(ret);
			})();
	      })
}

这样基本功能就具备了,如果还想做得更完善的话,其他还应该有哪些功能呢?多文件支持,队列管理,取消当前上传。。。有兴趣的朋友可以思考实现,想设计完成一个能满足大多数用户需求的轮子,着实不易,向无私的开源奉献者致敬。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用Umbrello学习工厂模式

工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口&#xff0c; 或者有共同的抽象父类。 当系统扩展需要添加新的产品对象时&#xff0c;仅仅需要添加一个具体对象以及一个具体工厂对 象&#xff0c;原有工厂对象不需要进行任何修改&#xff0c;也不…

小程序设计二

八、使用背景图片&#xff08;background-image) 注意&#xff1a; url不能指定为本地地址可以将图片转化为base64方式使用。使用网络地址&#xff1a; background-image: url(https://img1.baidu.com); 考虑到版权问题&#xff0c;这里没有放具体路径。 使用base64格式指…

【Vue】可拖拽排序表格组件的实现与数据保存

1、描述 使用el-table-draggable组件来创建一个可拖拽的表格。 表格中的数据存储在tableData数组中&#xff0c;每个对象都有sortOrder、id、name和age属性。 当用户拖拽表格行并释放时&#xff0c;handleRowOnEnd方法会被调用&#xff0c; 更新tableData中每个对象的sortO…

SpringBoot 缓存

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 目录 一、缓存的作用二、SpringBoot启用缓存三…

腾讯云邮件推送如何设置?群发邮件的技巧?

腾讯云邮件推送功能有哪些&#xff1f;怎么有效使用邮件推送&#xff1f; 腾讯云邮件推送以其稳定、高效的特点&#xff0c;受到了众多企业的青睐。那么&#xff0c;腾讯云邮件推送如何设置呢&#xff1f;又有哪些群发邮件的技巧呢&#xff1f;下面AokSend就来详细探讨一下。 …

Express进阶升级

Express进阶升级&#x1f199; 本篇文章&#xff0c;学习记录于&#xff1a;尚硅谷&#x1f3a2; 文章简单学习总结&#xff1a;如有错误 大佬 &#x1f449;点. 前置知识&#xff1a;需要掌握了解&#xff1a; JavaScript基础语法 、Node.JS环境API 、前端工程\模块化、Expr…

nvm基本使用

nvm基本使用 文章目录 nvm基本使用1.基本介绍2.下载地址3.常用指令 1.基本介绍 NVM是一个用于管理 Node.js 版本的工具。它允许您在同一台计算机上同时安装和管理多个 Node.js 版本&#xff0c;针对于不同的项目可能需要不同版本的 Node.js 运行环境。 NVM 主要功能&#xff…

【Redis | 第十篇】Redis与MySQL保证数据一致性(两种解决思路)

文章目录 10.Redis和MySQL如何保证数据一致性10.1双写一致性问题10.2数据高度一致性10.3数据同步允许延时10.3.1中间件通知10.3.2延迟双删 10.Redis和MySQL如何保证数据一致性 10.1双写一致性问题 Redis作为缓存&#xff0c;它是如何与MySQL的数据保持同步的呢&#xff1f;特…

PHP 错误 Unparenthesized `a ? b : c ? d : e` is not supported

最近在一个新的服务器上测试一些老代码的时候得到了类似上面的错误&#xff1a; [Thu Apr 25 07:37:34.139768 2024] [php:error] [pid 691410] [client 192.168.1.229:57183] PHP Fatal error: Unparenthesized a ? b : c ? d : e is not supported. Use either (a ? b : …

『FPGA通信接口』串行通信接口-SPI

文章目录 1.SPI简介2.控制时序3.Dual、Qual模式4.例程设计与代码解读5.SPI接口实战应用5.1时序要求5.2仿真时序图5.3代码设计 6.传送门 1.SPI简介 SPI是串行外设接口&#xff08;Serial Peripheral Interface&#xff09;的缩写&#xff0c;通常说SPI接口或SPI协议都是指SPI这…

将文件导入数据库

#include <stdio.h> #include <sqlite3.h> #include <string.h> int main(int argc, const char *argv[]) { //打开数据库 sqlite3 *db NULL; if(sqlite3_open("./dict.db",&db) ! SQLITE_OK){ printf("sqlite…

5G随身WiFi推荐测评:品速5G VS 格行5G随身WiFi,随身wifi哪个品牌网速好?性价比更高?

玩游戏卡顿遭吐槽&#xff0c;直播掉线成笑柄&#xff0c;4G网络已难满足需求。5G随身wifi虽受追捧&#xff0c;但价格较高令人犹豫。面对众多品牌&#xff0c;随身WiFi哪个品牌靠谱呢&#xff1f;性价比高呢&#xff1f;今天就来测评一下口碑最好的无线随身WiFi格行5G随身wifi…

新能源车载芯片分析

新能源汽车市场正迸发出巨大的活力&#xff0c;传统主机厂和新势力都纷纷推出各种车型&#xff0c;打起了价格战&#xff0c;各种新技术让人眼花缭乱。当前&#xff0c;战场硝烟弥漫&#xff0c;新能源汽车公司犹如春秋时期的各诸侯国。车载芯片作为新能源汽车的关键组成部分&a…

NDK 基础(一)—— C 语言知识汇总

1、数据类型 在 C 语言中&#xff0c;数据类型可以分为如下几类&#xff1a; 基本数据类型&#xff1a; 整数类型&#xff08;Integer Types&#xff09;&#xff1a;是算数类型&#xff0c;包括如下几种&#xff1a; int&#xff1a;用于表示整数数据&#xff0c;通常占用四个…

nvm 切换 Node 版本失败

创建vue3项目时&#xff0c;需要切换到更高版本的 node&#xff0c;于是使用 nvm (node 包版本管理工具)进行版本切换 切换版本时&#xff0c;显示成功&#xff0c;但再次查看当前 node 版本时&#xff0c;发现没切换过来。 解决方法&#xff1a; where node 查看node的安装…

车道分割YOLOV8-SEG

车道分割YOLOV8-SEG&#xff0c;训练得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV的DNN调用&#xff0c;支持C,PYTHON,ANDROID开发 车道分割YOLOV8-SEG

深圳工厂车间降温通风设备

深圳工厂降温方案多种多样&#xff0c;可以根据工厂的具体情况和需求来选择合适的方案。以下是一些常见的降温方案&#xff1a; 通风换气&#xff1a;通过安装负压风机或冷风机等设备&#xff0c;加强通风换气&#xff0c;将室内热空气排出&#xff0c;吸入室外相对凉爽的空气…

零基础俄语培训哪家好,柯桥俄语培训

1、Мощный дух спасает расслабленное тело. 强大的精神可以拯救孱弱的肉体。 2、Единственное правило в жизни, по которому нужно жить — оставаться человеком в лю…

WSL及UBUNTU及xfce4安装

如何拥有Linux服务器&#xff1f; wsl 是适用于 Linux 的 Windows 子系统&#xff08;Windows Subsystem for Linux&#xff09;。是一个为在Windows 10和Windows Server 2019上能够原生运行Linux二进制可执行文件&#xff08;ELF格式&#xff09;的兼容层&#xff0c;可让开发…

Docker 的数据管理 端口映射 容器互联 镜像创建

一 Docker 的数据管理 1 管理 Docker 容器中数据主要有两种方式&#xff1a; 数据卷&#xff08;Data Volumes&#xff09; 数据卷容器&#xff08;DataVolumes Containers&#xff09;。 1.1 数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机…
最新文章