大文件分片上传并发
我这边使用的是boostrap-fileimput
初始化文件上传框
$(document).ready(function () {$("#file-upload_import").fileinput({uploadUrl: "#",language: "zh", //设置语言showPreview: true,autoReplace: true,// uploadUrl: "/uact/uploadfile", //上传的地址uploadExtraData: { type: "1012-0001" },allowedFileExtensions: ["json"], //接收的文件后缀,allowedPreviewTypes: ["image"], //可以预览的文件类型// initialPreviewAsData: File,// maxFileSize:10485760, //10GshowUpload: false,maxFileCount: 1,minFileCount: 1,previewTemplates: {generic: '<div class="file-preview-frame" id="{previewId}" data-fileindex="{fileindex}" data-template="{template}">\n' +'</div>\n'},dropZoneTitle: "请选择一个json文件上传",// validateInitialCount: true,// showCaption: true,fileActionSettings: {// 在预览窗口中为新选择的文件缩略图设置文件操作的对象配置showRemove: true, // 显示删除按钮showUpload: false, // 显示上传按钮showDownload: false, // 显示下载按钮showZoom: false, // 显示预览按钮showDrag: false, // 显示拖拽},});})
分片和重传
var succeed = 0;
var fail_parts = []async function progress(percent, $element) {var progressBarWidth = percent * $element.width() / 100;$element.find('div').animate({ width: progressBarWidth }, 500).html(percent + "% ");
}function updateProgress(percentage) {$('.progress .progress-bar').attr('data-transitiongoal', percentage).progressbar({ display_text: 'fill' });
}function generateUUID() {// 生成全局uuidvar d = new Date().getTime();if (window.performance && typeof window.performance.now === "function") {d += performance.now();}var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {var r = (d + Math.random() * 16) % 16 | 0;d = Math.floor(d / 16);return (c == "x" ? r : (r & 0x3) | 0x8).toString(16);},)return uuid;
}const form = document.getElementById('upload-form');
const fileInput = document.getElementById('file-upload_import');
form.addEventListener('submit', async (e) => {e.preventDefault();$("#upload").attr("disabled", "disabled");const file = fileInput.files[0];if (!file) {alert("至少选择一个文件")return}const chunkSize = 10 * 1024 * 1024; // 10MB 分片大小// const chunkSize = 1 * 1024; // 1KB 分片大小let upload_id = generateUUID()// 切割文件const chunks = [];let offset = 0;while (offset < file.size) {const chunk = file.slice(offset, offset + chunkSize);chunks.push(chunk);offset += chunkSize;}$('.progress .progress-bar').attr('data-transitiongoal', 0).progressbar({ display_text: 'fill' });// 逐个上传分片const urls = [];for (let i = 0; i < chunks.length; i++) {const formData = new FormData();formData.append('chunk', chunks[i]);formData.append("upload_id", upload_id)formData.append('index', i);formData.append('size', file.size)urls.push({url: "你的分片上传地址",param: formData})}try {concurRequest(urls, 6).then(ret => {setTimeout(() => {$(document).trigger('chunksUploaded', [fail_parts, chunks, upload_id]);}, 1000);})} catch (error) {console.log("分片上传错误:" + error.data[0].index)fail_parts.push(error.data[0]);}
});$(document).on('chunksUploaded', async function (event, fail_parts, chunks, upload_id) {// 重传失败分片if (fail_parts.length > 0) {let retry_urls = [];for (let ele of fail_parts) {const formData = new FormData();formData.append('chunk', chunks[ele.index]);formData.append("upload_id", ele.upload_id)formData.append('retry', true)formData.append('index', ele.index)retry_urls.push({url: "你的分片上传地址",param: formData})}try {concurRequest(retry_urls, 3).then(ret => {console.log("重传分片成功!",res);})} catch (error) {console.log("重传分片" + error.msg + ":" + part.index)}}setTimeout(() => {$("#upload").removeAttr("disabled");if (fail_parts.length == 0) {const formData = new FormData();formData.append('total_chunks', chunks.length);formData.append("upload_id", upload_id);$.ajax({url: '/mongodb/import/merge/',method: 'POST',data: formData,processData: false,contentType: false,success: function (data) {if (data.status === 0) {alert('文件上传成功!');}}})} else {alert('文件上传失败,请稍后重新上传');}}, 2000);})
并发方法
/**
* 并发请求
* @param {string[]} urls 待请求的url数组
* @param {number} maxNum 最大的并发数
*/
function concurRequest(urls, maxNum) {return new Promise(resolve => {if (urls.length === 0) {/* 先考虑边界问题 */resolve([]);return;}const results = [] //存储请求结果并返回let index = 0; //下一个请求的url下标let count = 0; //计算请求的数量async function request() {if (index === urls.length) {return;}const i = index;const url = urls[index].url;const res = urls[index].param;index++try {let ret = await fetch(url, {method: "POST",body: res,});results[i] = ret //不能用push,因为这样就会出现异步完成优先写入不符合要求。var percent = ((index / urls.length).toFixed(2)) * 100;updateProgress(percent);} catch (error) {results[i] = err} finally {count++if (count === urls.length) {resolve(results);}request();}}const times = Math.min(maxNum, urls.length);for (let i = 0; i < times; i++) {request();}})
}
相关文章:
大文件分片上传并发
我这边使用的是boostrap-fileimput 初始化文件上传框 $(document).ready(function () {$("#file-upload_import").fileinput({uploadUrl: "#",language: "zh", //设置语言showPreview: true,autoReplace: true,// uploadUrl: "/uact/uploa…...
数据结构——基于顺序表实现通讯录
一、. 基于动态顺序表实现通讯录 1.1 功能要求 1)⾄少能够存储100个⼈的通讯信息 2)能够保存⽤⼾信息:名字、性别、年龄、电话、地址等 3)增加联系⼈信息 4)删除指定联系⼈ 5)查找制定联系⼈ 6&…...
行业追踪,2023-11-03
自动复盘 2023-11-03 凡所有相,皆是虚妄。若见诸相非相,即见如来。 k 线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让…...
JSPv2之El
(一)EL的基本语法 1优点 1 jsp的java太长了,el自己的语言${ 开始 }结束 2el直接返回空字符转,而java直接报错 3使用“lt”代替“<”运算符,如果运算符后面是数字,在运算符 *EL取值时,没有数组的下标越界,没有…...
出现 gpg: cancelled by user时的处理方法
今天在使用git commit -S -m "comment" check in 代码的时候, 莫名其妙出现了以下错误: gpg: cancelled by user经过在网上查询资料, 本质原因是GnuPG没有$(tty)的读写权限,有以下两种解决方法是靠谱的: c…...
MySQL中表的增删改查
目录 一、CRUD 二、新增(Create) (1)语法 (2)单行数据全列插入 (3)多行数据指定列插入 三、查询(Retrieve) (1)语法 …...
web.py python服务器两种模板template使用方法
【版权声明】 本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。 更多python应用或算法总结请关注我的博客:https://blog.csdn.net/suiyingy,或”乐乐感知学堂“公众号。 web.py是Python Web框架之一,…...
Flutter 01 目录结构入门
一、Flutter目录结构: 二、Flutter入口文件、入口方法: 三、Flutter Demo: demo1: import package:flutter/material.dart;//MaterialApp 和 Scaffold两个组件装饰App void main() {runApp(MaterialApp(home: Scaffold(appBar: A…...
Esxi安装OpenWrt
最近折腾下软路由主要就是实现局域网内的上网。 1.StarWind V2V Converter下载 先去下载个StarWind V2V Converter,觉得麻烦我在网上有找到一个博主的地址点击这里。 这是官网地址传送门,然后一阵乱输入点击下载 然后 双击之后无脑下一步即可。 2.Op…...
tuple 简易实现(C++ 模板元编程)
std::tuple 在标准库里面,tuple主要有下面四个类模板 or 函数模板 tupletuple_sizetuple_elementget 在后续有实现:tuple_size_v tuple_size::value和tuple_element_t tuple_element::type。 事例Example: auto tup std::tuple<in…...
Http代理与socks5代理有何区别?如何选择?(二)
上篇文章我们基本分别了解了http代理与socks5代理的定义与优缺点,接下来我们继续来了解http代理与socks5代理之间的比较与区别。 一、两者的比较 1、功能比较 HTTP代理专门用于Web流量,并在处理HTTP和HTTPS协议方面非常高效。它们可以修改正在传输的数…...
java中main方法和@Test注解的区别
Java的main方法和Test注解在用途和功能上有很大的区别。 main方法是Java应用程序的入口点。当你运行一个Java程序时,JVM会首先查找具有public static void main(String[] args)签名的类,并从这个方法开始执行程序。main方法通常用于控制程序的启动、执行…...
C++进阶语法——STL 标准模板库(下)(Standard Template Library)【学习笔记(七)】
文章目录 STL 代码示例1、迭代器2、算法3、array容器示例4、vector示例5、deque(double ended queue,双端数组)示例6、list(链表)容器7、set示例8、map示例9、stack 示例10、queue示例11、priority_queue (…...
力扣:求最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 示例1: 输入: strs ["flower", "flow" , "flight"] 输出: "fl" 示例2: 输入: strs ["dog","racecar","car&…...
Redis入门04-消息通知
目录 Redis中的消息通知 命令行操作 Redis中的管道 Redis中的消息通知 Redis可以用作消息队列的中间件,它提供了一种轻量级、高性能的消息传递机制,适用于实时通信、任务队列、事件处理等各种应用。以下是有关如何使用Redis作为消息队列的一些重要信…...
关于idea使用的一些操作设置
关于idea使用的一些操作设置 1. 常用的一下设置1.1 快捷键相关1.2 配置自动生成注释(类、方法等)1.3 maven项目相关1.4 常见其他的一些操作设置 2. IntelliJ IDEA 取消param注释中参数报错提示3. idea同时打开多个文件,导航栏不隐藏、自动换行…...
CLion 2023.2.2(C ++ IDE智能代码编辑器)
CLion 2023是一款跨平台C/C集成开发环境(IDE)。它为Mac用户提供了高效的编程体验,帮助程序员们在Mac平台上进行C/C开发。 CLion 2023支持多种编译器和调试器,并具有强大的代码分析和导航功能。它还为用户提供了许多便捷的工具和插…...
企业级API资产如何管理
在当今数字化时代,API已成为企业开发和创新的重要工具,如何高效地管理和调度这些资产成为了企业发展的重要课题。API资产管理的出现,为企业解决了这一难题,通过合理管理和利用API资产,企业可以更好地推动业务发展&…...
Git https方式拉的代码IDEA推送代码报错
报错信息 fatal: could not read Username for ‘https://codehub-cn-south-1.devcloud.huaweicloud.com’: No such file or directory 18:18:39.885: [recovery_pattern] git -c credential.helper -c core.quotepathfalse -c log.showSignaturefalse push --progress --porc…...
C++ capacity()用法总结
1. 容器的容量 容器的size是指它已经保存的元素的数目;而capacity则是在不分配新的内存空间的前提下它最多可以保存多少元素。capacity(),size(),reserve(),resize()这几个都是不太容易区分的函数 functionmeancapacity()获得容…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
