上传超10MB文件至S3遇HTTP长度超限问题求解决方案
解决API Gateway限制下S3大文件上传问题(突破10MB限制)
上传大于10MB的图片或视频到S3时触发HTTP content length exceeded 10485760 bytes错误,核心原因是API Gateway默认最大请求限制为10MB,当前通过API Gateway中转上传的方式无法绕过该限制。
解决方案:预签名URL+客户端直传S3
绕开API Gateway中转,让客户端直接向S3上传文件,完全不受API Gateway的10MB限制。具体实现步骤如下:
1. 修改后端逻辑:仅生成预签名URL
移除原来通过multer接收文件并中转到S3的逻辑,后端只负责生成带上传权限的预签名URL返回给前端。
修改后的后端代码示例:
const s3Client = new S3Client({ useAccelerateEndpoint: true, region: region, credentials: { accessKeyId: access_key_id, secretAccessKey: secret_key_id }, }); // 生成预签名URL的接口,接收前端传来的文件名和文件类型 const generatePresignedUrl = async (req, res) => { const { fileName, fileType } = req.body; if (!fileName || !fileType) { return res.status(400).json({ error: '文件名和文件类型不能为空' }); } // 根据文件类型分配存储文件夹 const folderName = fileType.startsWith('image/') ? 'media_images' : 'media_videos'; // 生成唯一的S3存储Key const s3Key = `${folderName}/${fileType.split('/')[0]}-${uuidv4()}-${fileName}`; const command = new PutObjectCommand({ Bucket: bucket, Key: s3Key, ContentType: fileType // 指定文件类型,确保S3正确识别 }); try { const uploadUrl = await getSignedUrl(s3Client, command, { expiresIn: 3600 }); // URL有效期1小时 return res.json({ key: s3Key, uploadUrl }); } catch (err) { console.error('生成预签名URL失败:', err); return res.status(500).json({ error: '生成上传链接失败' }); } };
2. 前端实现直传逻辑
前端选择文件后,先向后端请求预签名URL,再直接用PUT请求将文件上传到该URL:
async function uploadFileToS3(file) { // 第一步:向后端获取预签名URL const urlResp = await fetch('/api/generate-presigned-url', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ fileName: file.name, fileType: file.type }) }); const { uploadUrl, key } = await urlResp.json(); // 第二步:直接上传文件到S3 const uploadResp = await fetch(uploadUrl, { method: 'PUT', headers: { 'Content-Type': file.type }, body: file }); if (uploadResp.ok) { console.log('文件上传成功,S3存储Key:', key); // 可将key存入后端数据库,用于后续文件访问 } else { console.error('文件上传失败'); } }
3. 关键配置注意
- S3 Bucket CORS设置:必须允许前端域名的PUT请求,示例配置:
<CORSConfiguration> <CORSRule> <AllowedOrigin>https://你的前端域名.com</AllowedOrigin> <AllowedMethod>PUT</AllowedMethod> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration> - IAM权限:生成预签名URL使用的IAM账号需拥有
s3:PutObject权限,对应目标Bucket和存储路径。 - 超大文件优化:如果文件超过100MB,建议使用S3分段上传(Multipart Upload),预签名URL同样支持分段上传的每个分片。
内容的提问来源于stack exchange,提问作者Shah Mubashir Ul Haq
相关产品推荐
相关产品推荐

