名称: vercel-blob 描述: Vercel Blob 对象存储,为 Next.js 提供 CDN。用于文件上传(图像、PDF、视频)、预签名 URL、用户生成内容、文件管理,或遇到 BLOB_READ_WRITE_TOKEN 错误、文件大小限制、客户端上传令牌错误。
关键词: vercel blob, @vercel/blob, vercel storage, vercel file upload, vercel cdn, blob storage vercel, client upload vercel, presigned url vercel, file upload nextjs, image upload vercel, pdf upload, video upload, user uploads, multipart upload, streaming upload, blob cdn, vercel assets, file download 许可证: MIT
Vercel Blob (对象存储)
状态: 生产就绪
最后更新: 2025-12-14
依赖: 无
最新版本: @vercel/blob@2.0.0
快速开始(3 分钟)
1. 创建与配置
# 在 Vercel 仪表板:存储 → 创建数据库 → Blob
vercel env pull .env.local
创建:BLOB_READ_WRITE_TOKEN
2. 安装
bun add @vercel/blob
3. 上传文件(服务器操作)
'use server';
import { put } from '@vercel/blob';
export async function uploadFile(formData: FormData) {
const file = formData.get('file') as File;
const blob = await put(file.name, file, {
access: 'public',
contentType: file.type
});
return blob.url;
}
4. 基本操作
import { put, del, list } from '@vercel/blob';
// 上传
const blob = await put('path/file.jpg', file, { access: 'public' });
// 删除
await del(blob.url);
// 列表与分页
const { blobs, cursor } = await list({ prefix: 'uploads/', limit: 100 });
关键规则
始终执行
| 规则 | 原因 |
|---|---|
| 使用客户端上传令牌进行客户端上传 | 永远不要向客户端暴露 BLOB_READ_WRITE_TOKEN |
显式设置 contentType |
正确浏览器处理 PDF、视频 |
使用 access: 'public' 进行 CDN 缓存 |
私有文件绕过 CDN |
| 上传前验证文件类型和大小 | 防止无效上传 |
| 使用路径名组织 | avatars/, uploads/, documents/ |
| 替换时删除旧文件 | 管理存储成本 |
绝不执行
| 规则 | 原因 |
|---|---|
向客户端暴露 BLOB_READ_WRITE_TOKEN |
安全漏洞 |
| 上传文件 >500MB 而不使用多部分上传 | 使用 createMultipartUpload API |
| 使用通用文件名 | 使用 ${Date.now()}-${name} 或 addRandomSuffix: true |
| 跳过文件验证 | 始终验证类型/大小 |
| 存储未加密的敏感数据 | 上传前加密 |
| 忘记处理分页 | list() 最多返回 1000 个文件 |
已知问题预防
此技能预防 10 个文档化问题:
| # | 错误 | 快速修复 |
|---|---|---|
| 1 | BLOB_READ_WRITE_TOKEN not defined |
运行 vercel env pull .env.local |
| 2 | 客户端令牌暴露 | 使用 handleUpload() 进行客户端上传 |
| 3 | 文件大小超出 (500MB) | 使用多部分上传 API |
| 4 | 错误的内容类型 | 设置 contentType: file.type |
| 5 | 无 CDN 缓存 | 使用 access: 'public' |
| 6 | 列表中缺少文件 | 使用游标分页 |
| 7 | 删除失败静默 | 使用 put() 返回的精确 URL |
| 8 | 上传超时 | 使用客户端上传处理大文件 |
| 9 | 文件名冲突 | 添加时间戳或 addRandomSuffix: true |
| 10 | 状态未更新 | 使用 onUploadCompleted 回调 |
参见: references/known-issues.md 查看完整解决方案及代码示例。
常见模式总结
| 模式 | 使用场景 | 关键 API |
|---|---|---|
| 头像上传 | 用户个人资料图像 | put, del |
| 受保护上传 | 私有文档 | put 使用 access: 'private' |
| 图像库 | 列表与分页 | list 与游标 |
| 客户端上传 | 大文件、进度 | upload, handleUpload |
| 多部分上传 | 文件 >500MB | createMultipartUpload, uploadPart |
| 批量操作 | 多个文件 | Promise.all, del([...]) |
| 图像处理 | 上传前优化 | sharp + put |
参见: references/common-patterns.md 查看完整实现。
客户端上传(关键模式)
服务器操作(令牌生成):
'use server';
import { handleUpload, type HandleUploadBody } from '@vercel/blob/client';
export async function generateUploadToken(body: HandleUploadBody) {
return await handleUpload({
body,
request: new Request('https://dummy'),
onBeforeGenerateToken: async (pathname) => ({
allowedContentTypes: ['image/jpeg', 'image/png', 'image/webp'],
maximumSizeInBytes: 5 * 1024 * 1024
}),
onUploadCompleted: async ({ blob }) => {
// 保存到数据库
await db.insert(uploads).values({ url: blob.url, pathname: blob.pathname });
}
});
}
客户端组件:
'use client';
import { upload } from '@vercel/blob/client';
const blob = await upload(file.name, file, {
access: 'public',
handleUploadUrl: '/api/upload'
});
配置
.env.local
# 通过 vercel env pull .env.local 创建
BLOB_READ_WRITE_TOKEN="vercel_blob_rw_xxxxx"
.gitignore
.env.local
.env*.local
何时加载参考文档
| 参考文档 | 加载时机… |
|---|---|
references/known-issues.md |
调试上传错误、令牌问题或 CDN 缓存问题 |
references/common-patterns.md |
实现头像上传、图库、客户端上传或多部分上传 |
依赖
{
"dependencies": {
"@vercel/blob": "^2.0.0"
}
}
免费层限制: 100GB 带宽/月, 500MB 最大文件大小
官方文档
- Vercel Blob: https://vercel.com/docs/storage/vercel-blob
- 客户端上传: https://vercel.com/docs/storage/vercel-blob/client-upload
- SDK 参考: https://vercel.com/docs/storage/vercel-blob/using-blob-sdk
- GitHub: https://github.com/vercel/storage
故障排除
| 问题 | 解决方案 |
|---|---|
BLOB_READ_WRITE_TOKEN not defined |
运行 vercel env pull .env.local |
| 文件大小超出 (>500MB) | 使用多部分上传 API |
| 客户端上传失败 | 使用 handleUpload() 服务器端 |
| 文件未删除 | 使用 put() 响应中的精确 URL |
令牌节省: ~60%(模式提取到参考文档) 错误预防: 100%(所有 10 个文档化问题) 准备就绪,可用于生产!