基于T3栈的Next.js应用生成用户专属CSV下载链接方案咨询
基于T3栈+Vercel+PlanetScale的CSV生成与安全下载方案
核心思路拆解
- 触发逻辑:用户提交表单完成后,或用户主动发起导出请求时,后端从PlanetScale拉取该用户专属的数据
- CSV生成:用轻量库或SaaS工具快速转换数据格式
- 安全存储与授权:将CSV上传到支持访问控制的对象存储,生成仅限该用户访问的临时下载链接
- 前端交互:把链接返回给用户,点击即可下载
便捷SaaS工具推荐
- Vercel Blob:Vercel原生存储服务,和你的部署环境无缝兼容,无需额外配置。支持生成带过期时间的预签名URL,仅持有链接的用户可下载,免费额度覆盖小流量场景。
- Cloudflare R2:无带宽费用,兼容S3 API,能轻松生成临时授权链接,和Vercel部署的项目配合顺畅。
- Supabase Storage:自带行级安全(RLS),可直接关联用户身份,自动控制文件访问权限,不用手动生成签名链接,适合熟悉T3生态的开发者。
极简代码实现示例(Next.js API路由)
以Vercel Blob为例,步骤如下:
- 安装依赖:
npm install @vercel/blob json2csv @planetscale/database - 编写API路由(
app/api/export-csv/route.js):
import { createClient } from '@planetscale/database'; import { Parser } from 'json2csv'; import { put, createSignedUrl } from '@vercel/blob'; import { auth } from '@clerk/nextjs'; // 假设用Clerk做身份验证,T3常用 export async function POST(req) { // 验证用户身份,确保只能导出自己的数据 const { userId } = auth(); if (!userId) return Response.json({ error: '未授权' }, { status: 401 }); // 1. 从PlanetScale拉取用户数据 const client = createClient({ url: process.env.DATABASE_URL }); const { rows } = await client.execute('SELECT * FROM submissions WHERE user_id = ?', [userId]); // 2. 生成CSV文件 const parser = new Parser(); const csvContent = parser.parse(rows); // 3. 上传到Vercel Blob const blobPath = `user-exports/${userId}-${Date.now()}.csv`; await put(blobPath, csvContent, { access: 'private' }); // 4. 生成1小时有效期的下载链接 const downloadUrl = await createSignedUrl(blobPath, { expiresIn: '3600s' }); // 5. 返回链接给前端 return Response.json({ downloadUrl }); }
关键注意事项
- 数据隔离:必须在数据库查询时校验用户ID,绝对禁止拉取其他用户的数据
- 链接过期:设置合理的过期时间(比如1小时),避免链接被恶意传播
- 大数据处理:如果数据量较大,改用流式生成CSV并上传,避免内存溢出
- 成本管控:优先选择免费额度适配的存储服务,小项目用Vercel Blob或Cloudflare R2足够
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

