SuperAPI AI 工具集

file-upload

前端与建站

查看项目

更新于 10-16 02:21

技能介绍

用途

该技能用于在 Next.js 应用中接入文件上传功能,采用直传存储(direct-to-storage)方式:由服务器生成预签名 URL,客户端直接 PUT 到存储服务,服务器不接触文件字节。资料将该技能定位为「当需要为 Next.js 应用添加上传功能时」使用,兼容 Vercel Blob、Cloudflare R2 和 AWS S3 三种存储提供方。

主要能力

技能提供从检测、配置到实现和验证的完整流程,并特别强调四类会静默破坏上传的问题:

  1. 桶未配置 CORS:浏览器直接向 R2/S3 发起 PUT 请求,若桶的 CORS 规则未允许来源,每次上传都会因 CORS 错误失败。Vercel Blob 会自动处理,R2 和 S3 不会。
  2. 只在客户端做 MIME 类型校验:<input> 上的 accept 属性只是表面限制,用户可绕过。必须在生成预签名 URL 时在服务端校验 MIME 类型。
  3. 生成预签名 URL 前未检查文件大小:若不限制,用户可上传 500MB 文件且会成功。应在 S3/R2 预签名 URL 上设置 ContentLengthRange 条件,或在初始请求中检查 Content-Length。
  4. 把预签名 URL 路径当作永久文件地址保存:预签名 URL 会过期,应保存永久公开 URL(或自建代理路由),而非预签名 URL。

使用方式

流程分为五个阶段:

阶段一:检测项目。运行 cat package.json | grep -E "@vercel/blob|@aws-sdk|@cloudflare",根据依赖判断提供方:@vercel/blob 对应 Vercel Blob;@aws-sdk/client-s3 对应 AWS S3;@cloudflare/workers-types 或 Wrangler 对应 Cloudflare R2;都没有则询问用户(在 Vercel 上默认 Vercel Blob)。

阶段二:询问用户。确认存储提供方(Vercel Blob / Cloudflare R2 / AWS S3)、文件类型(如图片、PDF 与图片、任意)、最大文件大小(图片默认 10MB,文档默认 50MB)以及文件是公开还是私有(公开可直接 URL 访问;私有需经 API 鉴权后提供)。

阶段三:提供方配置。Vercel Blob 安装 @vercel/blob,环境变量 BLOB_READ_WRITE_TOKEN。Cloudflare R2 安装 @aws-sdk/client-s3 @aws-sdk/s3-request-presigner,环境变量包括 R2_ACCOUNT_ID、R2_ACCESS_KEY_ID、R2_SECRET_ACCESS_KEY、R2_BUCKET_NAME、R2_PUBLIC_URL,并在 Cloudflare 控制台配置 CORS(允许来源、PUT/GET 方法、Content-Type 与 Content-Length 头,MaxAgeSeconds 3600)。AWS S3 使用相同依赖包,环境变量为 AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_REGION、AWS_BUCKET_NAME。

阶段四:上传 API 路由。在服务端生成预签名 URL 并完成校验。资料给出两种实现:Vercel Blob 使用 handleUpload(在 onBeforeGenerateToken 中做鉴权并设置 allowedContentTypes 与 maximumSizeInBytes,在 onUploadCompleted 中把 blob.url 写入数据库);R2/S3 使用 getSignedUrl 配合 PutObjectCommand,先在服务端校验 contentType 与 size,生成带 expiresIn: 300(5 分钟)的预签名 URL,并返回永久公开 URL。

阶段五:上传组件。components/file-upload.tsx 使用 XMLHttpRequest 的 upload.onprogress 显示上传进度,先请求 /api/upload 获取预签名 URL,再直接 PUT 到存储,成功后回调公开 URL。

验证清单

资料附带一份验证清单:类型校验在 API 路由而非仅 accept 属性;大小检查在生成预签名 URL 前;鉴权在生成预签名 URL 前;R2/S3 桶已配置 CORS;只保存永久公开 URL;预签名 URL 过期时间不超过 5 分钟;展示上传进度而非仅旋转图标;错误状态显示具体错误信息;测试上传 .exe 文件应在服务端被拒绝;测试上传 50MB 文件应在生成预签名 URL 前被拒绝。

适用场景与限制

适用于在 Next.js 应用中添加上传功能,尤其是托管在 Vercel 上的应用或使用 R2/S3 的场景。资料未提供除上述三种存储提供方之外的选项,也未说明其他框架的适配方式。技能未涉及价格、收费或性能数据。