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

Next.js API路由间歇性出现405 Method Not Allowed错误

问题分析与解决方案

核心问题定位

你遇到的是Vercel部署的Next.js API路由间歇性接收GET请求(前端实际发送POST),导致405错误,结合现象和代码,从以下几个方向排查解决:

1. 修复API路由的致命错误

你的API路由末尾重复调用了响应方法:

res.status(200).json(results);
res.status(200).json(results);

在Next.js中,响应对象只能被发送一次,重复调用会触发服务器内部异常,可能导致Vercel边缘层的异常处理逻辑篡改请求方法或响应状态。立即删除其中一行,保证响应仅发送一次。

2. 规避浏览器预加载与Vercel缓存干扰

搜索引擎对话框场景下,浏览器可能会对输入框关联的请求发起预加载(Prefetch),用GET方法提前获取资源,这会导致API路由收到GET请求,干扰正常POST请求。

解决方法:

  • 在API路由中添加禁止缓存的响应头:
    // 在返回响应前添加
    res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
    res.setHeader('Pragma', 'no-cache');
    res.setHeader('Expires', '0');
    
  • 前端请求中也添加禁止缓存的头:
    const response = await fetch(`/api/search/get-initial-results`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Cache-Control": "no-store"
      },
      body: JSON.stringify({ currentTab })
    });
    

3. 解决前端竞态条件

你的useEffect依赖currentTab,切换标签时会触发防抖后的updates回调,短时间内多次切换可能导致多个请求并发,部分请求被浏览器取消后,Vercel边缘层可能将其识别为异常请求,引发方法篡改。

优化方案:添加请求取消逻辑,避免竞态:

const getInitialResults = React.useCallback(async () => {
  const controller = new AbortController();
  try {
    const response = await fetch(`/api/search/get-initial-results`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ currentTab }),
      signal: controller.signal
    });

    const res = await response.json();
    if (res.error) {
      setResults(null);
      setStatus("error");
      return;
    }
    setResults(res);
    setStatus("idle");
  } catch (error) {
    if (error.name !== 'AbortError') {
      setStatus("error");
    }
  }
  return () => controller.abort();
}, [currentTab]);

4. 检查Vercel路由配置

确认vercel.json中没有意外将POST请求转为GET的重写规则,若存在如下干扰规则需删除:

{
  "rewrites": [
    // 此类规则可能篡改请求方法,需移除
    { "source": "/api/search/get-initial-results", "destination": "/api/search/get-initial-results", "method": "GET" }
  ]
}

验证步骤

  1. 先修复API路由的重复响应问题,重新部署到Vercel;
  2. 添加禁止缓存的响应头,测试搜索引擎对话框的请求;
  3. 观察Vercel日志,确认是否还有GET请求记录;
  4. 若仍有问题,添加请求取消逻辑解决竞态条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 03:01:13