首页 > 其他分享 >js 大文件分割/分片上传

js 大文件分割/分片上传

时间:2023-11-14 17:55:34浏览次数:27  
标签:files js file 分片 progress fileData total 上传

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>uploadFile</title>
<style></style>
</head>
<body>
<input type="file" id="file" multiple />
<br />
<br />
<button id="btn">上传</button>

<script>
var uploadFile;
document.querySelector("#file").addEventListener(
"change",
(e) => {
var files = e.target.files;
if (!files.length) return;

uploadFile = new CutFileAndUpload({
files,
apiUpload: (fileData) => {
//接口请求 返回当前文件数据

/**
* fileData = {
file: file, //当前文件
succeed: 0, //已经上传的片数
shardSize: this.size, //以2MB为一个分片
shardCount: 0, //总片数
start: 0, //截取开始位置
end: 0, //截取结束位置
}
*/

//构造一个表单 表单字段根据后端接口而定
let fdata = new FormData();
//计算切割文件单个分片
let base64 = fileData.file.slice(fileData.start, fileData.end);
// fdata.append("base64", base64, fileData.file.name);
// fdata.append("name", fileData.file.name);
// fdata.append("total", fileData.shardCount); //总片数
// fdata.append("numbers", fileData.succeed + 1); //当前是第几片

//接口请求
setTimeout(() => {
//更新文件数据
uploadFile.updateFileData();
}, 2000);
},
progress: (progress, total) => {
//progress 当前文件进度百分比
//total 总进度百分比
console.log(progress, total);
},
success: () => {
//上传成功回调
console.log("全部上传完成");
e.target.value = "";
},
});
},
false
);
document.querySelector("#btn").addEventListener(
"click",
() => {
uploadFile.uploadFile();
},
false
);

/**
*
* @param {*} options
*/
function CutFileAndUpload(options) {
this.files = options.files || []; //要上传的文件列表
this.progress = options.progress; //上传进度
this.success = options.success; //成功回调
this.apiUpload = options.apiUpload;

this.fileArr = []; //文件列表切割后的文件数据
this.fileIndex = 0; //上传到第几个文件
this.size = 2 * 1024 * 1024; //分片单位 以2MB为一个分片
this.uploading = false; //上传状态

this.cutFile();
}
CutFileAndUpload.prototype = {
constructor: CutFileAndUpload,
cutFile() {
var files = this.files;

if (!files.length) {
console.log("请选择要上传的文件");
return;
}

for (var i = 0; i < files.length; i++) {
var file = files[i];
let fileData = {
file: file,
succeed: 0, //已经上传的片数
shardSize: this.size, //分片单位
shardCount: 0, //总片数
start: 0, //截取开始位置
end: 0, //截取结束位置
};
fileData.shardCount = Math.ceil(
fileData.file.size / fileData.shardSize
); //总片数
this.fileArr.push(fileData);
}
},
uploadFile() {
if (!this.fileArr.length) {
console.log("请选择要上传的文件");
return;
}

var fileData = this.fileArr[this.fileIndex];
//计算每一片的起始与结束位置
fileData.start = fileData.succeed * fileData.shardSize;
fileData.end = Math.min(
fileData.file.size,
fileData.start + fileData.shardSize
);

//计算文件单个分片
// let base64 = fileData.file.slice(fileData.start, fileData.end);
// console.log(fileData);

this.uploading = true;

//接口请求
this.apiUpload && this.apiUpload(fileData);
},
updateFileData() {
//更新文件数据
var fileData = this.fileArr[this.fileIndex];
fileData.succeed++;
var progress = parseInt(
(fileData.succeed / fileData.shardCount) * 100
);
var total;

if (fileData.succeed === fileData.shardCount) {
//单个文件上传完成
this.fileIndex++;
total = parseInt((this.fileIndex / this.fileArr.length) * 100);
this.progress && this.progress(progress, total);
if (this.fileIndex == this.fileArr.length) {
//列表的全部文件上传完成
this.uploading = false;
this.fileIndex = 0;
this.fileArr = [];
this.success && this.success();
} else {
this.uploadFile();
}
} else {
total = parseInt((this.fileIndex / this.fileArr.length) * 100);
this.progress && this.progress(progress, total);
this.uploadFile();
}
},
};
</script>
</body>
</html>

 

参考文章:http://blog.ncmem.com/wordpress/2023/11/14/js-%e5%a4%a7%e6%96%87%e4%bb%b6%e5%88%86%e5%89%b2-%e5%88%86%e7%89%87%e4%b8%8a%e4%bc%a0/

欢迎入群一起讨论

 

 

标签:files,js,file,分片,progress,fileData,total,上传
From: https://www.cnblogs.com/songsu/p/17832194.html

相关文章

  • WebGL_0019:three.js 欧拉角和四元数
    1,这篇说说欧拉角和四元数,欧拉角和四元数的优缺点是老生常谈的话题了,使用条件我就不多说了,我只说一下使用方法。1.欧拉角(Euler)欧拉角描述一个旋转变换,通过指定轴顺序和其各个轴向上的指定旋转角度来旋转一个物体。下面我们开看看它的方法1.set(x:number,y:number,z:......
  • JavaScript - js生成 txt 文件
    JavaScript-js生成txt文件/***方法定义*/functiondownload(filename,text){varelement=document.createElement('a');element.style.display='none';varcontent=encodeURIComponent(text);element.setAttribute('href&#......
  • git快速上传代码
    ①gitinit;初始化git,之后在文件夹里有.git文件,这个需要勾选才能查看。②gitremoteaddtesthttps://gitee.com/luo-xuesong/my-fisrt-test.git这里的test是自定义的,https://gitee.com/luo-xuesong/my-fisrt-test.git是远程仓库③gitbranch-a这里是查看分支④gitpu......
  • JSON.stringify
    当使用JSON.stringify函数时,第二个参数是一个数组或一个函数,用于控制序列化过程中对象的属性。第三个参数是一个用于控制缩进的数字或字符串,用于美化输出的可选参数。让我们通过一个例子来说明:假设我们有以下JavaScript对象:constperson={name:'John',age:30,a......
  • vuejs3.0 从入门到精通——Pinia——定义Store
    定义Store Store是用defineStore()定义的,它的第一个参数要求是一个独一无二的名字:import{defineStore}from'pinia'//你可以对`defineStore()`的返回值进行任意命名,但最好使用store的名字,同时以`use`开头且以`Store`结尾。(比如`useUserStore`,`useCartStore......
  • js实现大文件上传——分片上传方法
    当前端在开发过程中遇到上传文件需求,如果是上传头像、图片小文件之类的,可以正常按上传流程处理。但是当遇到上传大文件需求时,几个G或者十几个G,那么需要将这么大的文件分割成许多小片段分别上传,这种实现思路称为分片上传。实现分片上传,精髓就是将文件分割成小片段,此时我们需要用到......
  • js 计算两个地点坐标之间的间距
    /***计算两个地点坐标之间的间距*@param{array}location1[lon:string,lat:string]地点坐标*@param{array}location2[lon:string,lat:string]地点坐标*/exportfunctioncalculateDistance(location1,location2){ constearthRadius=6371//地球半......
  • 原生JS实现视频截图
    视频截图效果预览利用Canvas进行截图要用原生js实现视频截图,可以利用canvas的绘图功能ctx.drawImage,只需要获取到视频标签,就可以通过drawImage把视频当前帧图像绘制在canvas画布上。constvideo=document.querySelector('video')constcanvas=document.createElement('c......
  • 表格数据拖拽排序 sortable.js
    需求拖拽表格的行数据,实现排序。问题拖拽后调用接口,但视图没变,还是原来的顺序场景:拖拽表格行数据后,tableDataArr中数据的orderNum值会改变,实现拖拽换序。期望情况:页面根据更改后的orderNum重新排序。实际情况:接口数据变了,但是页面行数据没有改变。也就是说,页面没有实现......
  • app直播源代码,JS 替换日期的横杠为斜杠
    app直播源代码,JS替换日期的横杠为斜杠例如1:   vardt="2010-01-05";      vardt=dt.replace("-","/");    //只替换第一个“-”:2010/01-05  alert(dt); ​例如2:   vardt="2010-01-05";     vardt=dt.replace(/-/g,"/&q......