当前位置: 首页 > news >正文

vue实现小程序oss分片上传

随着小程序越来越普及,小程序上传文件必不可少,那么上传的文件大小就不可控了,小则几mb,大到好几百mb,小文件还可以,但是一到超过200mb或稍微再大些的小程序就很容易上传失败,导致功能不能继续进行。以下我们就来解决这个问题,将大文件实现分片上传

温馨提示,不要看内容多,其实很好理解,实在看起来头疼的,就运行起代码来,逐行打印就明白了,希望能帮到你。代码在最后,加油!!!

这是一份在前端(uni-app/小程序)直接对接阿里云 OSS 的“分片上传”实现,采用新版签名算法 OSS4-HMAC-SHA256(俗称 SigV4)。

v4签名官方算法地址:在Header中包含V4签名(推荐)_对象存储(OSS)-阿里云帮助中心

服务端获取sts访问凭证官方文档地址:使用STS临时访问凭证访问OSS_对象存储(OSS)-阿里云帮助中心

开发准备:安装依赖:npm install crypto-js

流程是:

  • 取 STS 临时凭证;
  • 先发起初始化分片(Init)拿到 UploadId;
  • 并发读取本地文件片段,逐片 PUT;
  • 最后 POST 完成分片(Complete),把各分片的 ETag 上报,生成最终对象。

关键概念与规范

  • CanonicalRequest:参与签名的“规范化请求字符串”,由 6 行组成:Method、CanonicalURI、CanonicalQueryString、CanonicalHeaders、AdditionalHeaders、PayloadHash。
  • StringToSign:把 CanonicalRequest 做 SHA256,再与算法名、时间、credentialScope 拼成最终待签名字符串。
  • Authorization:用派生出来的签名密钥对 StringToSign 做 HMAC-SHA256,形成签名后,连同访问键与 AdditionalHeaders 一起写入该头。
  • UNSIGNED-PAYLOAD:上传流式/分片时,不对包体求哈希,x-oss-content-sha256 与 PayloadHash 都写 UNSIGNED-PAYLOAD,以避免前端为大包体计算 sha256 的高开销。
  • 对象元数据 Content-Type 的确定时机:在“初始化分片”时确定,也就是你代码里把 content-type 设为真实文件类型的原因;后续 PUT/Complete 不会改变它。

代码分层与每段意义

  • 工具层
  • toHex、hmacSHA256、sha256HexOfString、sha256HexOfArrayBuffer:签名/哈希基础封装,arrayBufferToWordArray 用来把 ArrayBuffer 转成 crypto-js 可用的 WordArray。
  • utf8ToArrayBuffer:把 XML 等字符串转为 ArrayBuffer。
  • encodeRFC3986/encodePath:路径/参数严格 RFC3986 编码(OSS4 要求)。
  • buildCanonicalQuery:把查询参数字典规整为“按 key 排序”的 query 串;特别注意空值参数需写成 ?uploads(无等号)。
  • toLowerKeys/trimAndJoinHeaders/signedHeadersListExcluding:规整请求头(小写、去多空格、按 key 排序);AdditionalHeaders 是“参与签名的头名列表”,此实现特意把 content-type 排除在列表外,但它仍出现在 CanonicalHeaders 内。
  • 签名层
  • getSigningKey:按阿里规范派生签名密钥:aliyun_v4 + secret → kDate → kRegion → kService(oss) → kSigning('aliyun_v4_request')。
  • buildAuthorization:构建 CanonicalRequest、StringToSign、Authorization 字符串,返回三者用于调试/发送。
  • 时间
  • nowToDateTimeZ:产生 UTC 格式 YYYYMMDDTHHMMSSZ,作为 x-oss-date 与签名时间。时间漂移过大服务器会拒绝。
  • 本地文件读与 HTTP
  • statFile/readFileSlice:小程序文件系统读文件、按偏移读取分片。
  • requestBuffer:uni.request 的薄封装。
  • asyncPool:并发池,限制同一时间的分片上传并发数。
  • XML 辅助
  • parseXmlTag:解析 OSS 返回的 XML 指定标签。
  • buildCompleteXML:按 PartNumber 升序拼出 CompleteMultipartUpload XML。
  • guessContentType:按后缀猜测 Content-Type,用于 Init 请求,确保最终对象是正确媒体类型(mp4/mov/mp3 等)。

主流程 multipartUpload(opts)

   入参:filePath、objectKey、partSizeMB、maxConcurrency、onProgress、fetchSts。
  • 校验入参,statFile 获取总大小。
  • await fetchSts() 获取 STS(AK、SK、Token、bucket、region 等)。
  • 计算域名与地区:
  •     endpointRegion:形如 oss-cn-beijing
  •     signingRegion:形如 cn-beijing
  • 重要的 URI 分离:
  •     canonicalUriForSign = /${bucket}/${encodePath(objectKey)}(仅用于签名)
  •     canonicalUriForReq = /${encodePath(objectKey)}(真实请求路径)
  • 计算对象 MIME:objectContentType = guessContentType(objectKey)。
1) 初始化分片(POST ?uploads)
  • 头:host、x-oss-date、x-oss-security-token、x-oss-content-sha256: UNSIGNED-PAYLOAD、content-type: 对象真实类型。
  • 签名时用 canonicalUriForSign;请求 URL 用 canonicalUriForReq。
  • 解析响应的 UploadId。
2) 计算分片列表
  • partSize = max(100KB, partSizeMB);生成 partNumbers = [1..N]。
3) 上传每个分片(PUT ?partNumber=&uploadId= 并发)
  • 本地 readFileSlice 读 ArrayBuffer。
  • 头:content-type: application/octet-stream、x-oss-content-sha256: UNSIGNED-PAYLOAD 等。
  • 成功读取响应头 ETag,保存 [{PartNumber, ETag}]。
  • 进度回调 onProgress(loaded, total)。
4) 完成分片(POST ?uploadId=)
  • Body:CompleteMultipartUpload XML(ArrayBuffer)。
http://www.dtcms.com/a/346792.html

相关文章:

  • 2025年Java在中国开发语言排名分析报告
  • AI Common Notify :统一 AI 编程工具通知的小工具
  • LLM - Agent核心架构:四大“身体”部件
  • 【Spring Boot】集成Redis超详细指南 Redis在Spring Boot中的应用场景
  • GEO优化服务:智能时代营销新赛道的中国引领者——全球行业格局与发展趋势观察
  • react相关知识
  • 鸿蒙中内存泄漏分析
  • 爬虫基础学习-robots协议,以及request各种请求方式的实操
  • 解决Conda访问官方仓库失败:切换国内镜像源的详细教程
  • Python爬虫入门指南:从零开始的网络数据获取之旅
  • 【51单片机】【protues仿真】基于51单片机冰箱系统
  • MYSQL-约束
  • 自学嵌入式第二十六天:数据结构-哈希表、内核链表
  • 【Day 11】238.除自身以外数组的乘积
  • Trae 编辑器在 Python 环境缺少 Pylance,怎么解决
  • 构建现代高并发服务器:从内核机制到架构实践
  • Spring把「手动」的复杂裹成了「自动」的温柔
  • PostgreSQL15——查询详解
  • 【51单片机】【protues仿真】基于51单片机宠物投食器系统
  • Qt图像裁剪实时显示尺寸实现
  • Qt5 高级功能
  • 当 AI 学会 “理解” 人类:自然语言处理的进化与伦理边界
  • 商品与股指类ETF期权买卖五档Tick分钟级历史行情数据分析
  • 【KO】前端面试三
  • GPT-5:天变了吗?还是风停了?
  • 基于Python的农作物病虫害防治网站 Python+Django+Vue.js
  • MySQL奔溃,InnoDB文件损坏修复记录
  • [2025CVPR-目标检测方向]PointSR:用于无人机视图物体检测的自正则化点监控
  • 尤弥尔传奇能够进行挂机搬砖吗?
  • AI实现超级客户端打印 支持APP 网页 小程序 调用本地客户端打印