You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js+Vercel+Cloudinary生产环境仅出现405错误求助

生产环境Vercel部署后/api/upload接口405 Method Not Allowed错误排查求助

开发环境下图片上传至Cloudinary完全正常,但部署在Vercel的生产环境调用/api/upload接口时出现405(Method Not Allowed)错误。已尝试调整请求头、修改CORS配置、切换Axios/Fetch、降级Next.js、更换npm包等多种方法,均未解决问题。以下是相关代码、配置及错误详情,恳请帮忙排查:

前端代码

const createImagesSrc = async (imageFileToAdd: File[]): Promise<AxiosResponse | null> => {
  try {
    const formData = new FormData();
    imageFileToAdd.forEach((image) => {
      formData.append("images", image);
    });
    const uploadResponse = await axios.post("/api/upload", formData, {})
    if (uploadResponse.status === 200) {
      uploadResponse.data.uploadResponses.forEach(
        (response: any, index: number) => {
          imageSrc.push(response.secure_url);
        }
      );
      return uploadResponse;
    } else {
      console.error("Failed to upload images");
      return null;
    }
  } catch (error) {
    console.error(error);
    return null;
  }
};

后端代码

cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.API_KEY,
  api_secret: process.env.API_SECRET,
});

export async function POST(request: Request) {
  const data = await request.formData();
  const files = data.getAll("images");

  if (files.length === 0) {
    return NextResponse.json({
      success: false,
      message: "No images to upload.",
    });
  }

  const uploadPreset = "yfhyp9my";
  const uploadResponses: any[] = [];

  for (const file of files) {
    // @ts-ignore
    const bytes = await file.arrayBuffer();
    const buffer = Buffer.from(bytes);

    const response = await new Promise((resolve, reject) => {
      cloudinary.uploader
        .upload_stream({ upload_preset: uploadPreset }, (error, result) => {
          if (error) {
            reject(error);
          }
          resolve(result);
        })
        .end(buffer);
    });
    uploadResponses.push(response);
  }
  return NextResponse.json({ success: true, uploadResponses });
}

next.config.js配置

const nextConfig = {
  async headers() {
    return [
      {
        // matching all API routes
        source: "/api/:path*",
        headers: [
          { key: "Access-Control-Allow-Credentials", value: "true" },
          { key: "Access-Control-Allow-Origin", value: "coolbananas.org, localhost:3000" },
          {
            key: "Access-Control-Allow-Methods",
            value: "GET,OPTIONS,PATCH,DELETE,POST,PUT",
          },
          {
            key: "Access-Control-Allow-Headers",
            value:
              "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version",
          },
        ],
      },
    ];
  },
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "res.cloudinary.com",
        port: "",
        pathname: "/jpsm83/image/upload/**",
      },
      {
        protocol: "https",
        hostname: "lh3.googleusercontent.com",
      },
      {
        protocol: "https",
        hostname: "restcountries.com",
      },
    ],
  },
};

错误信息

POST https://www.coolbananas.org/api/upload 405 (Method Not Allowed)
AxiosError {message: 'Request failed with status code 405', name: 'AxiosError', code: 'ERR_BAD_REQUEST', ...}

注:Vercel环境变量已配置完整,MongoDB数据可正常保存,但图片无法上传至Cloudinary,Cloudinary后台未找到CORS配置选项,现已陷入困境。

内容的提问来源于stack exchange,提问作者Joao Machado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 23:30:59