react大文件上传

目录

大文件上传优点:

大文件上传缺点:

 大文件上传原理:

 为什么要用md5

实现流程:

部分代码1:

 部分代码2:​


大文件上传优点:

  1. 文件太大分片上传能加快上传速度,提高用户体验
  2. 能断点续传 如果上次上传失败或者中途离开的话下一次上传过的就不用重头开始了
  3. 已经上传过的文件根据HASH查询直接秒传

大文件上传缺点:

1.后台可能设置了请求时长限制,太久会上传失败(解决:后端不设置上传时长)

2.NGINX可能设置了文件上传的最大限制导致失败(解决:比如分片25M,nginx设置文件上传最大限度50M)

 大文件上传原理:

  1. 用户选择要上传的大文件,计算整个文件的MD5。
  2. 前端根据分片大小将文件切分成多个小块,计算每个分片文件的MD5。
  3. 逐个上传每个小块到服务器端。
  4. 服务器端接收并保存每个小块。
  5. 在服务器端,根据上传的小块将它们合并成完整的文件。

 为什么要用md5

        因为每个文件都会有自己专属独立的md5值,就像是每个人的身份证,比如我们在某个平台发布视频,将视频文件二次上传的时候就会遇到不容易过审的原因,同一个MD5就有很大的机率显示搬运被退回。刚好后端同学也可以通过MD5这种特性来判断上传的文件是否完整。

如何快速计算文件的 md5 值呢? 我们使用 js-spark-md5 这个库

实现流程:

         在upload组件上传文件的钩子函数beforeUpload() 中:

  1.  获取切片文件:设置切片文件大小、每次上传的开始字节,每次上传的结尾字节。文件切片的核心是使用Blob 对象的 slice 方法:
    var blob = file.slice([start [, end [, contentType]]]};
    start 和 end 代表 Blob 里的下标,表示被拷贝进新的 Blob 的字节的起始位置和结束位置。contentType 会给新的 Blob 赋予一个新的文档类型,很少使用。
  2.  计算分片文件的MD5
  3. 上传分片文件,断点续传(如何实现断点续传,关键点是后端需要记录文件文件切片的信息。用户在上传一个文件之前,先询问服务器,当前文件是否存在已经上传完毕的切片,如果存在的话,需要返回切片信息。前端根据返回的信息,调整当前的进度,上传未完成的切片)
  4. 检验分片数量及上传的结果,全部上传,文件合并
    1. 前端发送切片完成后,发送一个合并请求,后端收到请求后,将之前上传的切片文件合并。(上面展示的代码采用 这个)
    2. 后台记录切片文件上传数据,当后台检测到切片上传完成后,自动完成合并。
    3. 创建一个和源文件大小相同的文件,根据切片文件的起止位置直接将切片写入对应位置。

部分代码1:

export default class Project extends React.PureComponent {construction (props){this.state({file: {},fileplanNumber: 0, // 上传文件进度的百分比fileUploadState: '', // 上传文件的状态,fail失败, success成功interFaceStart: '', // 文件上传时的分片文件下标, 作用于断点续传})}beforeUpload = (file) => {this.setState({file,  // 把file存起来})let reader = new FileReader();let md5 = '';reader.onload = (event) => {const spark = new SparkMD5.ArrayBuffer;spark.append(e.target.value);md5 = spark.end();axios.post('', {md5,id, // 后端需要的}).then((res) => {const { fileId, start, finish, message } = res.data.data;if(res.data.code !== 200){message.error(message);}if(finish && finish === 'true'){this.setState({file: {}, // 等于true,表示上传完成了fileplanNumber: 0, // 上传文件进度的百分比})message.error(message);return;}// 请求成功后this.setState({fileId,interFaceStart: start, // 文件上传时,分片文件下标,为了断点续传}, () => {this.getSliceFile() // 获取文件切片})})}reader.readArrayBufffer(file);return false;
}// 获取文件切片
getSliceFile = async () => {const { search, cataList } = this.props;  const { file, fileId, interFaceStart } = this.state;const archiveId = cataList && cataList[cataList.length - 1].archiveId;const fileSize = file.size; // 文件的大小const piece = 1024 *1024 * 25; // 每片25Mlet start = 0; // 每次上传开始字节let index = 1;let end = start + piece; // 每次上传的结尾字节const chunksList = [];while(start < fileSize){const current = Math.min(end, fileSize) // 两者中取最小的const blob = file.slice.call(file, start, current);// 计算分片文件的MD5let sliceFileMD5 = '';sliceFileMD5 = await this.getSliceFileMD5(blob );// 拼接分片信息数据chunksList.push({file: blod,index,sliceFileMD5,});start = current;end = start + piece;index += 1;}// 检验分片数量,开始上传if (chunksList && chunksList.length) {const chunks = chunksList.slice(interFaceStart); // 分片上传的结果let resultList = 0;// 循环分片数据for(const item of chunks){// 调用接口上传分片内容const resultFile  = await this.uploadSliceFile(item, chunks);//记录上传结果resultList += 1;// 一次失败,结束后续上传if(!resultFile){break;}}// 检验分片数量,分片上传结果数量,全部上传完成,调用合并接口if(resultList === chunks.length){const { fileList } = this.state;axios.post('', { fileId,fileName: file.name,businessId: archiveId,businessType: 'archive',}).then((res) => {if(res.data.code !== 200){message.error(res.data.message)}message.success('上传成功!')// 调接口,刷新页面axios.post('', {pageNum: 1,pageSize: 10,archiveId,orderBy: '',sort: '',  }).then(res => {if(res.code !== 200){message.error(res.message)};})this.setState({file: {},fileId: '',fileUploadState: null,fileplanNumber: 0,fileList,interFaceStart: 0,});})} else {this.setState({fileUploadState: fail,});}}
}// 计算分片文件的MD5getSliceFileMD5 = (blob) => {return new Promise((resolve, reject) => {const sliceFileReader = new FileReader();let sliceFileMD5  = '';sliceFileReader.onerror = reject;sliceFileReader.onload = (event) => {const spark = new SparkMD5.ArrayBuffer();spark.append(event.target.result)sliceFileMD5 = spark.end();// 返回分片MD5resolve(sliceFileMD5);}sliceFileReader.readAsArrayBuffer(blob);})}// 上传分片文件uploadSliceFile = (fileMap, chunks) => {return new Promise((resolve, reject) => {const { sliceFileMD5, file, index } = fileMap;const fileBlob = new File([file], 'AAA.exe', { type: 'application/x-msdownload' })const { fileId } = this.state;const formData = new FormData();formData.append('fileId', fileId);formData.append('MD5', sliceFileMD5);formData.append('partSequence', index);formData.append('fileBlob', fileBlob);axios.post('', {formData,headers: {'Content-Type': 'multipart/form-data',}}).then(res => {if(res.data.code !== 200){message.error(res.data.message)return false;}const fileplanNumber = (index / chunks.length) * 100;this.setState({fileplanNumber,});resolve(true);})})}}

 部分代码2:

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

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

相关文章

简单工程模式

代码实现 //simpleFactory.h #ifndef _SimpleFactory_H_ #define _SimpleFactory_H_#include <iostream> #include <exception> #include <string>using namespace std;class Operation { protected:double _numberA 0;double _numberB 0; public:Operat…

MybatisX插件使用

Mybatis X插件 MybatisX 是一款基于 IDEA 的快速开发插件&#xff0c;为效率而生。MybatisX官网&#xff1a;https://baomidou.com/pages/ba5b24/#%E5%8A%9F%E8%83%BD安装方法&#xff1a;打开 IDEA&#xff0c;进入 File -> Settings -> Plugins&#xff0c;输入 mybat…

三维控件中定位一个点_vtkPointWidget

开发环境&#xff1a; Windows 11 家庭中文版Microsoft Visual Studio Community 2019VTK-9.3.0.rc0vtk-example参考代码 demo解决问题&#xff1a;允许用户使用三维光标在三维空间中定位一个点。关键类vtkPointWidget , 光标具有轮廓边界框、轴对齐十字准线和轴阴影&#xff…

AD7021C 触摸感应加灯光调节芯片IC 可用于触摸台灯、触摸玩具灯等

AD7021C触摸感应 IC 是为实现人体触摸界面而设计的集成电路。可替代机械式轻触按键&#xff0c;实现防水防尘、密封隔离、坚固美观的操作界面。使用该芯片可以实现 LED 灯光亮度调节&#xff0c;方案所需的外围电路简单&#xff0c;操作方便。确定好灵敏度选择电容&#xff…

【华为OD题库-033】经典屏保-java

题目 DVD机在视频输出时&#xff0c;为了保护电视显像管&#xff0c;在待机状态会显示"屏保动画”&#xff0c;如下图所示,DVD Logo在屏幕内来回运动&#xff0c;碰到边缘会反弹:请根据如下要求&#xff0c;实现屏保Logo坐标的计算算法 1、屏幕是一个800 * 600像素的矩形&…

Vue3 provide 和 inject 实现祖组件和后代组件通信

provide 和 inject 能够实现祖组件和其任意的后代组件之间通信&#xff1a; 一、provide 提供数据 我们在祖组件中使用provide 将数据提供出去。 使用provide 之前需要先进行引入&#xff1a; import { provide } from "vue"; 语法格式如下&#xff1a; provide(&q…

山西电力市场日前价格预测【2023-11-23】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-11-23&#xff09;山西电力市场全天平均日前电价为148.77元/MWh。其中&#xff0c;最高日前电价为420.40元/MWh&#xff0c;预计出现在18:00。最低日前电价为0.00元/MWh&#xff0c;预计出…

微信小程序开发学习——页面布局、初始导航栏与跳转

1.盒模型 要求实现效果如图所示&#xff1a; 所有WXML元素都可以看作盒子&#xff0c;在WXSS中"box model”这一术语是用来设计和布局时使用盒模型本质上是一个盒子&#xff0c;封装周围的WXML元素它包括: 边距&#xff0c;边框&#xff0c;填充和实际内容&#xff0c;模…

RAW RGB YUV数据差异

目录 颜色与色彩空间 RAW图像 RGB图像 YUV图像 颜色与色彩空间 颜色 颜色是人眼感知到的现象&#xff0c;它是由光波的频率和强度所决定的&#xff0c;仅仅存在于人的眼睛和大脑中&#xff0c;因此为了方便描述颜色&#xff0c;引入了色彩空间。色彩空间 色彩空间&#xff…

C语言--数组与指针--打印字符串的n种方式

一.知识背景 一维数组名的含义 arr一般表示数组的起始地址&#xff08;除了两种例外&#xff09; 1.在定义数组的同一个函数中(不是形参),求sizeof(arr),求整个数组的字节数 2.在定义数组的同一个函数中(不是形参),&arr1,加整个数组的大小 (经常考试) 3.除上面以外,arr都表…

和鲸 × 暨大经管:高效 SAAS 服务持续赋能交叉学科应用型数据人才培养

随着新一轮科技革命与产业变革的加速演进&#xff0c;拥有学科背景的应用型数据科学人才逐渐成为我国政产学研各界的人力资源需求重点。为响应需求&#xff0c;国家愈发重视新生力量数据思维与意识的培养&#xff0c;各高校也纷纷探索如何以新兴信息技术赋能传统主流学科。 在…

达索系统SOLIDWORKS流体分析网格划分失败,大多是这2种原因

SOLIDWORKS Flow Simulation 是直观的流体力学 (CFD) 分析软件&#xff0c;该软件功能强大、操作人性化&#xff0c;快速轻松的分析产品内部或外部流体的流动情况&#xff0c;以用来改善产品性能和功能。 当流体分析运行网格划分时&#xff0c;提示失败。 这是由于凸起面与圆…

【LeetCode刷题】--43.字符串相乘

43.字符串相乘 方法一&#xff1a;做加法&#xff0c;模拟竖式乘法的方法计算乘积 class Solution {public String multiply(String num1, String num2) {if(num1.equals("0") || num2.equals("0")){return "0";}String res "0";//nu…

Hadoop -hdfs的读写请求

1、HDFS写数据&#xff08;宏观&#xff09;&#xff1a; 1、首先&#xff0c;客户端发送一个写数据的请求&#xff0c;通过rpc与NN建立连接&#xff0c;NN会做一些简单的校验&#xff0c;文件是否存在&#xff0c;是否有空间存储数据等。 2、NN就会将校验的结果发送给客户端…

解决requests库进行爬虫ip请求时遇到的错误的方法

目录 一、超时错误 二、连接错误 三、拒绝服务错误 四、内容编码错误 五、HTTP错误 在利用requests库进行网络爬虫的IP请求时&#xff0c;我们可能会遇到各种错误&#xff0c;如超时、连接错误、拒绝服务等等。这些错误通常是由目标网站的限制、网络问题或我们的爬虫代码中…

前端性能优化总结

这里写目录标题 页面性能测试工具测试指标 前端页面性能常见的问题前端页面性能优化常见策略及方案dns优化------预解析域名&#xff08;异步进行&#xff09;http请求优化减少请求次数同时多开持久连接 前面面试url从输入到确认搜索发生了什么js介绍new一个对象的过程&#xf…

Linux 进程等待

在2号手册里查wait&#xff08;&#xff09;。wait()等待任意一个子进程的状态。 wait&#xff08;&#xff09;等待成功会返回该子进程的id,返回失败会返回-1&#xff1a; 小实验 子进程的退出码 子进程执行work()&#xff0c;父进程wait子进程。 子进程跑完5秒之后就e…

GCANet_Gated context aggregation network for image dehazing and deraining

2019、中科大港科、有代码 Chen D, He M, Fan Q, et al. Gated context aggregation network for image dehazing and deraining[C]//2019 IEEE winter conference on applications of computer vision (WACV). IEEE, 2019: 1375-1383. GitHub - cddlyf/GCANet: Implementation…

丢掉破解版,官方免费了!!!

哈喽&#xff01;大家好。 几天不见&#xff0c;今天给大家带来一款海外的神器&#xff0c;官方宣布完全免费&#xff0c;但仅限于个人与教育用途&#xff0c;切勿商用噢&#xff01; 不要看这个软件名字普普通通&#xff0c;实际上内蕴乾坤&#xff01; 接下来看我给大家炫一…

队列的实现和OJ练习(c语言)

目录 概念 队列的实现 利用结构体存放队列结构 为什么单链表不使用这种方法&#xff1f; 初始化队列 小提示&#xff1a; 队尾入队列 队头出队列 获取队头元素 获取队尾元素 获取队列中有效元素个数 检测队列是否为空 销毁队列 最终代码 循环队列 队列的OJ题 …