NextJS+ tRPC+AWS S3图片上传遇跨域403错误求助
解决NextJS + tRPC + AWS S3图片上传跨域问题
问题场景
开发基于NextJS的应用,采用tRPC和AWS S3实现图片上传功能,提交表单时触发跨域错误,提示Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin。
相关代码
表单提交逻辑
async function onSubmit(data: z.infer<typeof schema>) { console.log(data) const { file } = data if (!file) return null // Get upload url const { url, fields } = await createURL() const formData = new FormData() Object.entries(fields).forEach(([key, value]) => { formData.append(key, value as string) }) formData.append('file', file) const uploadResponse = await fetch(url, { method: 'POST', body: formData, }) if (uploadResponse.ok) { console.log("Upload successful!") } else { console.error('S3 Upload Error:', uploadResponse) } console.log(uploadResponse) }
tRPC预签名URL路由
import { createPresignedPost } from "@aws-sdk/s3-presigned-post"; export const fileRouter = createTRPCRouter({ createURL: protectedProcedure.mutation(async ({ ctx }) => { const { userId } = ctx const contentType = "image/" const file = await db.file.create({ data: { userId } }) const presignedPost = await createPresignedPost(s3Client, { Bucket: process.env.AWS_BUCKET!, Key: `${userId}/${file.id}`, Conditions: [ ['content-length-range', 0, 10485760], // up to 10 MB ['starts-with', '$Content-Type', contentType], ], Fields: { acl: 'public-read', 'Content-Type': contentType, }, Expires: 600, }) return presignedPost }) })
错误信息
[Error] Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. Status code: 403 [Error] Fetch API cannot load https://next-stack-app.s3.us-east-2.amazonaws.com/ due to access control checks. [Error] Failed to load resource: Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. Status code: 403 (next-stack-app.s3.us-east-2.amazonaws.com, line 0) [Error] Unhandled Promise Rejection: TypeError: Load failed (anonymous function) (index.esm.mjs:2196)
解决方案
1. 配置S3存储桶CORS规则
这是解决跨域问题的核心步骤:
- 登录AWS控制台,找到目标S3存储桶
- 切换到「权限」标签页,找到「跨域资源共享(CORS)」配置项
- 替换现有规则为以下内容(根据环境调整AllowedOrigins):
[ { "AllowedHeaders": ["*"], "AllowedMethods": ["GET", "POST", "PUT"], "AllowedOrigins": ["http://localhost:3000"], "ExposeHeaders": ["ETag"] } ]
注意:生产环境需将
AllowedOrigins替换为实际业务域名,例如["https://your-app-domain.com"]
2. 验证预签名Post配置
检查tRPC路由中的contentType设置:当前代码中contentType = "image/",虽能匹配所有图片类型,但建议改为"image/*"以更清晰;同时确保FormData中正确传递了文件的原始Content-Type(浏览器会自动为File对象设置,无需手动修改)。
3. 等待配置生效
AWS S3的CORS配置变更可能需要1-5分钟生效,配置完成后重新测试上传功能即可。
内容的提问来源于stack exchange,提问作者Santiago Padilla
相关产品推荐
相关产品推荐

