Skip to content

解决 Next.js 应用目录中 API 路由返回 404 问题

问题描述

当你使用 Next.js 13 或更新版本的 app 目录结构创建 API 路由时,可能会遇到 404 Not Found 错误。典型表现包括:

  • 在 Postman、curl 或浏览器中访问 API 路由返回 404
  • 本地开发和生产环境行为不一致
  • API 文件路径如 app/api/admin/all.js 但访问 /api/admin/all 失败

问题通常源于以下原因:

  1. 文件命名不符合 Next.js 13+ 的 app 路由规范
  2. next.config.js 中使用了不兼容的配置
  3. 请求处理方法不符合新路由系统的要求

解决方案一:规范 API 路由文件和导出方式

文件结构规范

在 Next.js 13+ 的 app 路由系统中,API 路由必须使用特定文件名:

  • 错误路径:app/api/admin/all.js
  • 正确路径:app/api/admin/route.js(对应 URL /api/admin

代码实现方法

按照新规范修改 API 处理逻辑:

javascript
import { NextResponse } from "next/server";
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

export async function GET(request) {
  // 获取查询参数示例
  const { searchParams } = new URL(request.url);
  const userId = searchParams.get('id');
  
  try {
    const admins = await prisma.admin.findMany();
    return NextResponse.json(admins, { status: 200 });
  } catch (error) {
    return NextResponse.json(
      { error: "Failed to get admins" },
      { status: 500 }
    );
  }
}

export async function POST(request) {
  try {
    const body = await request.json(); // 获取请求体数据
    // 处理数据逻辑...
    return NextResponse.json({ success: true }, { status: 201 });
  } catch (error) {
    return NextResponse.json(
      { error: "Invalid request data" },
      { status: 400 }
    );
  }
}

核心变更说明

  1. 文件名:必须为 route.js(或 TypeScript 使用 route.ts
  2. 导出方法:使用 HTTP 方法命名的导出函数(GET, POST等)
  3. 响应对象:必须使用 NextResponse 而不是传统的 res 对象
  4. 请求处理request 参数替代了原来的 reqres

重要

  • 每个路由文件只能包含一个 route.js
  • URL 路径由文件夹结构决定,不是文件名
  • 必须使用 GET, POST 等命名导出函数

解决方案二:修正 Next.js 生产配置

当 API 在本地运行正常但在生产环境(如 Vercel、Amplify)失败时:

问题根源

next.config.js 中设置了静态导出:

javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: "export", // ← 这会导致 API 路由失效
};
module.exports = nextConfig;

为什么静态导出会导致问题

output: "export" 会将应用构建为纯静态站点,API 路由作为动态服务器功能将无法工作

正确配置

移除静态导出配置,确保服务器功能正常运行:

javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
  eslint: {
    ignoreDuringBuilds: true,
  },
  images: { unoptimized: true },
  // 不要包含 'output: "export"' 
};

module.exports = nextConfig;

验证步骤

  1. 更新配置文件
  2. 重新构建项目:npm run build
  3. 检查构建输出确认包含 API 路由
  4. 重新部署到生产环境

生产环境最佳实践

  • 在 Vercel 等支持平台使用默认服务端渲染配置
  • 使用 Next.js 内置的 API 中间件处理扩展功能

常见问题补充

如何获取请求体数据?

使用标准 Web API 的 .json() 方法解析请求:

javascript
export async function POST(request) {
  try {
    const data = await request.json();
    // 使用 data...
  } catch (error) {
    return NextResponse.json(
      { error: "Invalid JSON" },
      { status: 400 }
    );
  }
}

如何处理其他 HTTP 方法?

为每个支持的 HTTP 方法单独创建导出函数:

javascript
export async function PUT(request) { /*...*/ }
export async function DELETE(request) { /*...*/ }
export async function PATCH(request) { /*...*/ }

总结关键要点

问题类型解决方案验证方法
文件命名错误文件必须命名为 route.js (在对应 API 文件夹内)检查文件路径是否符合 app/api/[path]/route.js
配置错误next.config.js 移除 output: 'export'检查生产构建是否存在 API 路由
方法定义错误使用 export async function GET(request) 语法确认导出方法名使用大写 HTTP 方法
响应错误使用 NextResponse.json() 返回响应确保导入 NextResponse

确保文件结构、配置和处理方法三者一致,即可解决 Next.js app 目录下的 API 404 问题。部署后如仍有问题,检查服务器日志获取详细错误信息,重点关注路由注册情况。