添加Cloudflare R2文件上传的提示
复制粘贴AI提示,为Next.js App Router项目添加Cloudflare R2预签名上传URL,并包含服务器端验证。
CursorClaude CodeCodexWindsurf Next.jsCloudflareTypeScript
将本提示交给您的AI代理,以实现使用预签名URL直接上传到R2 —— 将密钥保留在服务器端,避免常见的将文件字节路由通过Next.js服务器的错误。
主要提示
You are working in a Next.js App Router project using TypeScript.
Task: add Cloudflare R2 file upload via presigned PUT URLs.
Requirements:- Install `@aws-sdk/client-s3` and `@aws-sdk/s3-request-presigner` (R2 is S3-compatible).- Create a Server Action in `src/lib/actions/get-upload-url.ts` that: - Accepts `{ filename: string; contentType: string; sizeBytes: number }`. - Validates: `sizeBytes` must be <= 10_485_760 (10 MB); `contentType` must start with `image/`. - Uses `PutObjectCommand` + `getSignedUrl` to generate a 60-second presigned URL. - Returns `{ uploadUrl: string; publicUrl: string; key: string }`.- Store credentials in `.env`: `R2_ACCOUNT_ID`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `R2_BUCKET_NAME`, `R2_PUBLIC_URL`.- Create a client component `src/components/FileUploader.tsx` that: - Renders a file `<input accept="image/*" />`. - On change: calls the Server Action to get the presigned URL, then does a `fetch` PUT directly to R2, then shows the `publicUrl` as a preview. - Shows upload progress via `XMLHttpRequest` `progress` events (not fetch, which lacks progress).- Do not add any other dependencies. Do not modify `next.config.ts` unless required for image domains.
Stop and list all planned file changes before writing any code.实现说明
- R2使用S3 SDK,需要设置
endpoint: https://<accountId>.r2.cloudflarestorage.com和region: 'auto'。忘记设置region: 'auto'会导致签名错误。 - 预签名URL在服务器端生成;客户端永远不会看到
R2_SECRET_ACCESS_KEY。 - 如需公共存储桶访问,请在Cloudflare仪表板中打开R2存储桶的”公共访问”开关,并将生成的
r2.devURL作为R2_PUBLIC_URL提供。
预期文件更改
src/lib/actions/get-upload-url.ts (new)src/lib/r2.ts (new — S3Client singleton)src/components/FileUploader.tsx (new — Client Component).env.example (edited)package.json (edited)next.config.ts (edited — add r2.dev to images.remotePatterns)验收标准
- 在
FileUploader中选择文件将触发预签名URL获取,然后直接上传到R2。 - 大于10 MB的文件在任何网络请求之前被拒绝。
- 非图片MIME类型在服务器端被拒绝,并返回400等效错误。
- 上传完成后,公共URL预览将显示上传的图片。
测试命令
bun run typecheckbun run dev# upload a PNG < 10 MB via the component and confirm it appears in R2 bucket# attempt a 15 MB file and confirm rejection# attempt a .pdf and confirm rejection常见的AI错误
- 设置
region: 'us-east-1'而不是'auto',导致SignatureDoesNotMatch错误。 - 将文件字节路由通过Next.js服务器操作而不是直接上传到R2。
- 忘记在操作文件顶部调用
'use server'。 - 使用
fetch上传并丢失进度事件。
修复提示
The upload fails with `SignatureDoesNotMatch` or the file routes through the server.Fix in order:1. In `src/lib/r2.ts`, set `region: 'auto'` and `endpoint: https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com`.2. In `FileUploader.tsx`, use `XMLHttpRequest` with a `progress` event to PUT directly to the presigned URL — not fetch, and not a Server Action for the actual upload bytes.Show corrected diff only.