react+antd(upload)上传视频使用md5判断视频是否上传完整

文章讲述了在后台管理系统中,为确保视频上传的完整性,使用MD5校验文件。通过MD5的特性,确保文件在上传过程中未被篡改。文章指出了js-md5不适合用于文件MD5计算,并推荐使用crypto-js库。还提供了计算文件MD5的代码示例,以及在文件上传组件中应用的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

年前后台管理系统写了一个关于视频上传的需求,使用的是阿里的oss上传,限制大小也限制了500M。但昨天后端同学找了过来说能不能传给md5给他来判断是否上传完整,因为app端要用到这个视频,如果后台上传大文件的时候,没有上传完整,那么可能会出现问题。
于是我就百度了一下md5,MD5全称Message Digest Algorithm 5,即消息摘要算法第5版。

MD5特性:

1,长度固定:MD5加密后值固定长度是128位,使用32个16进制数字进行表示。
2,单向性/不可逆/恒定性:同一个文件在不同时间通过md5解析出来的消息摘要是一样的。但是这个消息摘要并不能逆向解析原始数据出来。
3,不可预测性:两个原始数据相差一个字母,解析出来就完全不一样。
特殊的:MD5是32位的,理论上是有限的,而世界上的数据是无限的,不同的文件可能也会生成重复的MD5值
经典例子:

# 数据源1:
d131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f89
55ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5b
d8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0
e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70
# 数据源2:
d131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f89
55ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5b
d8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0
e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70
# 有着相同的MD5值
79054025255fb1a26e4bc422aef54eb4

为什么要用md5

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

实现文件md5的计算

出现问题了,项目里原来用了 js-md5,这个md5来加密登陆密码的,然后用这个对视频文件加密,和后端md5计算出来的结果不一致。
看了一下js-md5

js-md5准确来说不算是加密,应该说是将密文序列化了,可以通过下列的网站将md5加密后的字符直接解析出来,因此安全性很低,也不符合刚刚介绍的MD5特性

解密网站点击

所以,换成crypto-js来进行解析:

通过自定义的密钥进行加解密,可以更灵活的加解密密文,但是因为密文的key在可以通过前端看到,所以加密的信息虽然通过解密网站无法解密,但是可以通过在前端得到的公共key进行解密,不过用在自己的业务逻辑里问题不大

代码如下:
业务代码:获取md5的方法

 const getMD5 = (value) => {
        let reader = new FileReader();
        // 读取文件 value
        reader.readAsArrayBuffer(value);
        return new Promise((resolve, reject) => {
            try {
                reader.onload = function () {
                  var wordArray = CryptoJS.lib.WordArray.create(reader.result);
                  var hash = CryptoJS.MD5(wordArray).toString(); // 计算其他加密算法,SHA1改为MD5、SHA256即可
                    resolve(hash)
                };
            } catch (error) {
                reject(error)
            }
        })
    }

在upload组件beforeUpload这个API中实现

const beforeUpload = async (file) => {
        // 计算图片或视频的md5
        const MD5 =  await getSha1(file)
        // 讲md5这个计算的值赋值给file对象文件,后续传给后端同学
        file.md5 = MD5
        return file
 }

总结

有点不想写,但是考虑到在写的时候能沉浸在知识的海洋,也能更加理解。还有就是以后自己还能看。好记性不如烂笔头。各位同学也多做笔记,一起学习哦

<think>好的,用户想了解如何在前端实现大文件分片上传,包括进度条和前端框架的应用。我需要结合之前提供的引用资料,整理出一个清晰的实现方案。首先,分片上传的基本步骤是文件切片、上传分片、合并分片,进度条需要跟踪每个分片的上传情况。 根据引用中的例子,比如引用[2]提到前端分片上传使用Promise.all可能有问题,引用[3]指出前端需要确保分片上传完成后再合并,可能需要轮询后端状态。引用[4]和[5]提到了生成唯一文件ID、断点续传的处理,比如调用接口获取已上传的分片信息,跳过已上传的部分。前端框架部分可能需要使用Vue或React来处理状态管理,比如引用[4]提到需要根据使用JS框架调整代码。 进度条的实现可以通过监听每个分片的上传进度,然后计算总体进度。引用[2]中的uploadProgress事件可以用来跟踪每个分片的上传百分比,然后汇总。同时,前端需要处理可能的错误,比如网络中断后的重试机制,引用[5]中的例子提到异常处理时重置变量并重新获取进度。 还需要注意文件切片的方法,使用Blob.prototype.slice来切割文件,生成分片列表。每个分片上传时携带唯一标识和分片序号,后端需要记录这些信息以便合并。前端框架部分可能需要使用axios或fetch API发送分片,结合async/await处理异步上传。 最后,要确保回答结构清晰,分步骤说明,并给出示例代码,同时推荐适用的前端框架和注意事项,如断点续传、MD5校验等。还要引用相关参考资料,比如引用[3]和[4]中的前端和后端协作的问题。</think>### 前端文件分片上传实现方案 #### 一、核心步骤 1. **文件分片** - 使用`Blob.prototype.slice`方法将文件切割为固定大小(如5MB)的分片 - 生成唯一文件标识(如MD5或`file.name + size + lastModified`组合) ```javascript const chunkSize = 5 * 1024 * 1024 // 5MB const chunks = [] let start = 0 while (start < file.size) { chunks.push(file.slice(start, start + chunkSize)) start += chunkSize } ``` 2. **分片上传** - 使用`FormData`携带分片数据、文件标识、分片序号 ```javascript const uploadChunk = async (chunk, index) => { const formData = new FormData() formData.append('fileId', fileId) formData.append('chunkIndex', index) formData.append('chunk', chunk) return axios.post('/upload/chunk', formData) } ``` 3. **进度监控** - 通过`axios`的`onUploadProgress`事件监听上传进度[^2][^4] ```javascript const config = { onUploadProgress: progressEvent => { const percent = Math.round( (progressEvent.loaded / progressEvent.total) * 100 ) updateProgress(index, percent) // 更新单个分片进度 } } ``` #### 二、进度条实现 1. **计算总体进度** ```javascript const totalProgress = chunksProgress.reduce((sum, p) => sum + p, 0) / chunks.length ``` 2. **可视化方案** - 使用`<progress>`原生标签 - 集成第三方库如`antd Progress`或`ElementUI`组件 - 自定义SVG动画(适用于复杂效果) #### 三、断点续传实现 1. 上传前调用接口获取已上传分片信息[^5] ```javascript const { uploadedChunks } = await axios.get(`/upload/progress?fileId=${fileId}`) ``` 2. 过滤已上传分片 ```javascript const needUpload = chunks.filter((_, index) => !uploadedChunks.includes(index)) ``` #### 四、推荐前端框架方案 1. **Vue3 + axios** ```vue <template> <input type="file" @change="handleFile"> <progress :value="progress" max="100"></progress> </template> <script setup> import { ref } from 'vue' const progress = ref(0) const handleFile = async (e) => { const file = e.target.files[0] // 分片上传逻辑 } </script> ``` 2. **React + fetch API** ```jsx function Uploader() { const [progress, setProgress] = useState(0) const uploadChunk = async (chunk, index) => { const formData = new FormData() // ...添加表单数据 const res = await fetch('/upload/chunk', { method: 'POST', body: formData, }) // 更新进度状态 } } ``` #### 五、优化建议 1. **并行控制**:使用`Promise.allSettled`控制并发数量(如同时上传5个分片) 2. **错误重试**:为每个分片设置重试机制(最多3次) 3. **MD5校验**:前端生成文件指纹,后端验证分片完整性 4. **内存优化**:使用Web Worker处理大文件分片计算[^3] #### 六、注意事项 1. **文件标识稳定性**:需确保重新上传相同文件时生成相同fileId[^4] 2. **跨域问题**:配置CORS头`Access-Control-Allow-Origin` 3. **进度精度**:分片越小进度更新越频繁,但会增加请求数量 4. **浏览器兼容性**:需处理IE浏览器的`Blob.slice`兼容问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只夏宇坤

你的鼓励是我持续创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值