S3文件上传出现PermanentRedirect错误求助
解决S3文件上传的PermanentRedirect错误
错误详情
上传文件到S3时出现以下永久重定向错误:
Error uploading to S3: PermanentRedirect: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint. les/next/dist/server/lib/start-server.js:140:13) { '$fault': 'client', '$metadata': { httpStatusCode: 301, requestId: '15FT2CFREYE2RZH4', extendedRequestId: 'bHgMekr6oM5JHOG2lrbV0hK//YMVz87yujbVeJx1Na4CbD7jFcCHPKgfinsbMRjOnIxVZHC0puE=', cfId: undefined, attempts: 1, totalRetryDelay: 0 }, Code: 'PermanentRedirect', Endpoint: 'doctors-kitchen.s3.eu-north-1.amazonaws.com', Bucket: 'doctors-kitchen', RequestId: '15FT2CFREYE2RZH4', HostId: 'bHgMekr6oM5JHOG2lrbV0hK//YMVz87yujbVeJx1Na4CbD7jFcCHPKgfinsbMRjOnIxVZHC0puE=' }
当前使用的路由代码
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3"; import { buffer } from "stream/consumers"; import uniqid from "uniqid"; export async function POST(req) { const data = await req.formData(); if (data.get("file")) { console.log("we have file", data.get("file")); const file = data.get("file"); const s3Client = new S3Client({ region: "ap-south-1", credentials: { accessKeyId: process.env.AWS_ACCESS_KEY, secretAccessKey: process.env.AWS_SECRET_KEY, }, }); const ext = file.name.split(".").slice(-1)[0]; const newFileName = uniqid() + "." + ext; const chunks = []; for await (const chunk of file.stream()) { chunks.push(chunk); } const buffer = Buffer.concat(chunks); const bucket = "doctors-kitchen"; try { await s3Client.send( new PutObjectCommand({ Bucket: bucket, Key: newFileName, ACL: "public-read", ContentType: file.type, Body: buffer, }) ); const link = "https://" + bucket + ".s3.amazonaws.com/" + newFileName; return Response.json(link); } catch (error) { console.error("Error uploading to S3:", error); return Response.json( { error: "Failed to upload to S3" }, { status: 500 } ); } } console.log(data); return Response.json(true); }
解决方案
错误核心原因是代码配置的S3区域与Bucket实际所在区域不匹配:错误信息里的Endpoint字段明确显示Bucket位于eu-north-1区域,但代码中设置的是ap-south-1,导致请求被强制重定向。
需要做两处修改:
修正S3Client的区域配置
将S3Client初始化时的region值从ap-south-1改为eu-north-1。修正返回的文件访问链接
原链接使用通用的s3.amazonaws.com域名,需要替换为对应区域的域名,避免后续访问文件时出现同样的重定向问题。
修改后的完整代码
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3"; import { buffer } from "stream/consumers"; import uniqid from "uniqid"; export async function POST(req) { const data = await req.formData(); if (data.get("file")) { console.log("we have file", data.get("file")); const file = data.get("file"); // 修正区域为Bucket实际所在的eu-north-1 const s3Client = new S3Client({ region: "eu-north-1", credentials: { accessKeyId: process.env.AWS_ACCESS_KEY, secretAccessKey: process.env.AWS_SECRET_KEY, }, }); const ext = file.name.split(".").slice(-1)[0]; const newFileName = uniqid() + "." + ext; const chunks = []; for await (const chunk of file.stream()) { chunks.push(chunk); } const buffer = Buffer.concat(chunks); const bucket = "doctors-kitchen"; const region = "eu-north-1"; try { await s3Client.send( new PutObjectCommand({ Bucket: bucket, Key: newFileName, ACL: "public-read", ContentType: file.type, Body: buffer, }) ); // 修正文件访问链接为对应区域的域名 const link = `https://${bucket}.s3.${region}.amazonaws.com/${newFileName}`; return Response.json(link); } catch (error) { console.error("Error uploading to S3:", error); return Response.json( { error: "Failed to upload to S3" }, { status: 500 } ); } } console.log(data); return Response.json(true); }
内容的提问来源于stack exchange,提问作者shriram choudhary
相关产品推荐
相关产品推荐

