
本文详解如何在不经过应用服务器中转的前提下,将超大文件(如 15gb)安全、高效地直传至 aws s3,核心方案是结合预签名分片上传(presigned multipart upload)与客户端分片库(如 evaporatejs),实现服务端轻量化的上传流程。
本文详解如何在不经过应用服务器中转的前提下,将超大文件(如 15gb)安全、高效地直传至 aws s3,核心方案是结合预签名分片上传(presigned multipart upload)与客户端分片库(如 evaporatejs),实现服务端轻量化的上传流程。
传统单次 POST 到预签名 URL 的方式受限于 HTTP 协议和浏览器/网关限制(例如 CloudFront 或 ALB 默认最大请求体为 5GB),无法满足超大文件上传需求。而真正的解决方案在于 客户端驱动的分片上传(Client-Side Multipart Upload):由前端将大文件切分为多个 Part(如每片 5–100MB),对每个 Part 单独向后端申请预签名 URL,再并发上传——整个过程完全绕过你的应用服务器的数据中转。
✅ 关键实现步骤
-
服务端提供三类 API 接口(均需鉴权):
-
POST /upload/init:初始化分片上传,返回uploadId和bucket/key -
GET /upload/presign?uploadId=xxx&partNumber=1&size=10485760:为指定 Part 返回预签名 URL(含x-amz-part-number、x-amz-upload-id等必要 header) -
POST /upload/complete:提交PartETag列表,完成合并
-
前端使用成熟分片上传库(推荐 EvaporateJS)
EvaporateJS 自动处理文件切片、并发控制、断点续传、失败重试及进度反馈。你只需实现其signerUrl配置项,指向你的预签名接口:
const evaporate = await Evaporate.create({
signerUrl: '/upload/presign',
awsKey: 'YOUR_TEMPORARY_CREDENTIALS_KEY', // 建议使用 IAM Role 或 STS AssumeRole 生成临时凭证
bucket: 'your-bucket-name',
computeContentMd5: true,
maxConcurrentParts: 5,
partSize: 10 * 1024 * 1024, // 10MB per part
});
evaporate.add({
name: file.name,
file,
complete: (data) => console.log('✅ Upload completed:', data),
progress: (progress) => console.log(`Upload progress: ${(progress * 100).toFixed(1)}%`),
});
⚠️ 注意事项:
- 绝不硬编码长期 AWS 密钥:服务端应通过 STS
AssumeRole动态颁发具备最小权限(仅限目标 Bucket 的s3:PutObject,s3:ListMultipartUploadParts,s3:CompleteMultipartUpload)的临时凭证;- 预签名 URL 必须包含必要 header:如
x-amz-part-number、x-amz-upload-id、content-type,否则 S3 将拒绝 Part 上传;- 启用 CORS 并显式允许自定义 Header:S3 Bucket 的 CORS 配置需包含
<allowedheader>x-amz-*</allowedheader>;- 服务端需校验 uploadId 有效性与用户权限:防止越权发起或完成他人上传任务;
- 建议添加上传生命周期管理:通过 S3 Lifecycle 规则自动清理
AbortIncompleteMultipartUpload的残留 Part(如 1 天后自动删除)。
该方案不仅显著降低服务器带宽与内存压力,还提升了用户体验(支持断点续传、秒传、进度可视化),是现代云原生应用处理大文件上传的标准实践。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











