解决 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
失败
问题通常源于以下原因:
- 文件命名不符合 Next.js 13+ 的 app 路由规范
- 在
next.config.js
中使用了不兼容的配置 - 请求处理方法不符合新路由系统的要求
解决方案一:规范 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 }
);
}
}
核心变更说明
- 文件名:必须为
route.js
(或 TypeScript 使用route.ts
) - 导出方法:使用 HTTP 方法命名的导出函数(
GET
,POST
等) - 响应对象:必须使用
NextResponse
而不是传统的res
对象 - 请求处理:
request
参数替代了原来的req
和res
重要
- 每个路由文件只能包含一个
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;
验证步骤
- 更新配置文件
- 重新构建项目:
npm run build
- 检查构建输出确认包含 API 路由
- 重新部署到生产环境
生产环境最佳实践
- 在 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 问题。部署后如仍有问题,检查服务器日志获取详细错误信息,重点关注路由注册情况。