文件存储与 OSS
问题
服务端如何处理文件上传和存储?S3/OSS 的使用方式和最佳实践是什么?
答案
文件存储方案
| 方案 | 适用场景 | 优缺点 |
|---|---|---|
| 本地磁盘 | 开发环境 | 简单,不适合生产 |
| 云对象存储 | 生产环境 | 可靠、CDN 加速、按量计费 |
| 数据库 BLOB | 小文件 | 简单,不推荐大文件 |
云存储服务对比
| 服务 | 提供商 | 特点 |
|---|---|---|
| S3 | AWS | 行业标准,生态最完善 |
| OSS | 阿里云 | 国内首选 |
| COS | 腾讯云 | 国内次选 |
| R2 | Cloudflare | 无出站流量费用 |
| Supabase Storage | Supabase | 开源,与数据库集成 |
上传方式
1. 服务端中转上传
server-upload.ts
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
const s3 = new S3Client({ region: 'us-east-1' });
app.post('/api/upload', upload.single('file'), async (req, res) => {
const file = req.file!;
const key = `uploads/${Date.now()}-${file.originalname}`;
await s3.send(new PutObjectCommand({
Bucket: 'my-bucket',
Key: key,
Body: file.buffer,
ContentType: file.mimetype,
}));
res.json({ url: `https://cdn.example.com/${key}` });
});
2. 签名直传(推荐)
presigned-upload.ts
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
// 后端:生成预签名 URL
app.post('/api/upload/presign', async (req, res) => {
const { filename, contentType } = req.body;
const key = `uploads/${Date.now()}-${filename}`;
const url = await getSignedUrl(s3, new PutObjectCommand({
Bucket: 'my-bucket',
Key: key,
ContentType: contentType,
}), { expiresIn: 300 }); // 5 分钟有效
res.json({ uploadUrl: url, fileUrl: `https://cdn.example.com/${key}` });
});
// 前端:直接上传到 OSS
const { uploadUrl, fileUrl } = await api.getPresignedUrl(file.name, file.type);
await fetch(uploadUrl, {
method: 'PUT',
body: file,
headers: { 'Content-Type': file.type },
});
签名直传优势
- 减轻服务器压力:文件不经过服务器,直接传到 OSS
- 上传更快:少了一次中转
- 节省带宽:服务器不消耗带宽
常见面试问题
Q1: 服务端中转上传和签名直传怎么选?
答案:
- 签名直传(推荐):大文件、高频上传、带宽敏感场景
- 服务端中转:需要对文件做预处理(压缩、水印)、安全要求高
Q2: 如何限制上传文件的大小和类型?
答案:
三层校验:
- 前端:
input accept+ File API 检查(易绕过,仅做体验优化) - 服务端:Content-Type + 文件头(magic number)检测
- OSS 策略:Bucket Policy 限制
Q3: 文件 URL 安全怎么处理?
答案:
- 公开文件:CDN 直接访问
- 私有文件:预签名 URL(带过期时间)
- 敏感文件:Referer 限制 + 签名 + 短期有效
Q4: 如何实现图片上传后自动处理?
答案:
- 上传到 OSS 后触发函数计算(如 Lambda)自动处理
- 使用 OSS 的图片处理参数:
?x-oss-process=image/resize,w_200 - CDN 图片处理服务(如 Cloudflare Images)
相关链接
- 大文件上传和下载 - 分片上传
- 设计图片处理 CDN 服务 - CDN 图片处理
- 设计大文件上传系统 - 文件上传系统设计