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

Axios+NextJS调用接口始终返回405方法不允许问题求助

问题分析

线上环境出现405错误的核心原因是跨域预请求(OPTIONS)未被正确处理:本地开发时同源请求不会触发OPTIONS预检查,而线上跨域场景下浏览器会先发OPTIONS请求验证权限,但当前代码既未在API路由中处理OPTIONS方法,也未在中间件中拦截响应,导致请求进入API路由的错误分支返回非法状态码;同时错误分支误用了406 Not Acceptable状态码,方法不允许的正确状态码应为405 Method Not Allowed。


解决方案

方案1:修改API路由直接处理OPTIONS请求

在API处理文件中新增OPTIONS方法的处理逻辑,直接返回200响应完成预检查:

import axios from 'utils/axios';

export default async function handler(req, res) {
  const {
    method,
    body: { currentPassword, password },
    headers: { authorization }
  } = req;

  // 优先处理OPTIONS跨域预请求
  if (method === 'OPTIONS') {
    res.status(200).end();
    return;
  }

  try {
    if (method === 'POST') {
      const { data } = await axios.post(
        `${process.env.REACT_BACKEND_URL}users/change-password`,
        {
          password,
          currentPassword
        },
        {
          headers: {
            Authorization: authorization
          }
        }
      );
      res.status(200).send(data);
    } else {
      res.setHeader('Allow', ['POST']);
      // 修正方法不允许的状态码为405
      res.status(405).end(`Method ${method} Not Allowed`);
    }
  } catch (error) {
    if (error.statusCode && error.statusCode !== 500) {
      res.status(error.statusCode).end(error.message);
    } else {
      res.status(500).end('Server Error');
    }
  }
}

方案2:在中间件层统一拦截OPTIONS请求

如果需要为所有API路由统一处理跨域预请求,修改中间件代码,直接对OPTIONS请求返回带CORS头的响应,无需进入API路由:

import { NextResponse } from 'next/server';

export function middleware(request) {
  // 拦截OPTIONS预请求直接返回响应
  if (request.method === 'OPTIONS') {
    const res = new NextResponse(null, { status: 200 });
    res.headers.append('Cache-control', 'no-store');
    res.headers.append('Access-Control-Allow-Credentials', 'true');
    res.headers.append('Access-Control-Allow-Origin', '*'); // 生产环境替换为实际前端域名
    res.headers.append('Access-Control-Allow-Methods', 'GET,DELETE,PATCH,POST,PUT');
    res.headers.append('Access-Control-Allow-Headers', '*');
    return res;
  }

  // 其他请求正常添加CORS头并继续执行
  const res = NextResponse.next();
  res.headers.append('Cache-control', 'no-store');
  res.headers.append('Access-Control-Allow-Credentials', 'true');
  res.headers.append('Access-Control-Allow-Origin', '*'); // 生产环境替换为实际前端域名
  res.headers.append('Access-Control-Allow-Methods', 'GET,DELETE,PATCH,POST,PUT');
  res.headers.append('Access-Control-Allow-Headers', '*');
  return res;
}

export const config = {
  matcher: '/api/:path*'
};

额外注意事项

  1. 生产环境禁止使用*作为Access-Control-Allow-Origin,替换为实际前端域名(如https://your-frontend-domain.com),避免安全风险
  2. 检查环境变量REACT_BACKEND_URL是否配置正确,确保转发路径无拼写错误
  3. 确认前端请求的Authorization头是否正确携带,避免后端返回错误触发API路由的异常分支

内容的提问来源于stack exchange,提问作者Julian Mendez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 06:11:21