Next.js 14 API路由本地正常但生产公网访问返回404
Next.js API路由公网访问404问题排查
应用配置
- Next.js版本:14.2.8
- Node.js版本:20.9.0
- Couchbase SDK:4.4.1
API路由路径:src/app/api/translations/route.ts
正常访问情况
- 本地开发环境:
http://localhost:8082/api/translations?lang=en返回预期结果 - 生产服务器本地(SSH访问):
http://localhost:3000/api/translations?lang=en运行正常
公网访问错误响应
通过公网URL(如https://example.com/api/translations?lang=en)访问时,收到以下404错误:
{ "error": "ERR001", "id": "b3b632e0349fa8fd3b5ca9fa4e578fd624617fb2ffbcef5aa6c6a029ac0e0d6f", "message": "No handler found for GET /api/translations", "source": "No handler found for GET /api/translations" }
路由代码实现
route.ts中的GET和PUT处理器代码:
import { connectToDatabase } from '../../../utils/couchbase'; export async function GET(req: Request) { const { translationsCollection } = await connectToDatabase(); const { searchParams } = new URL(req.url); const lang = searchParams.get('lang'); if (!lang) { return new Response(JSON.stringify({ message: "Language parameter 'lang' is required" }), { status: 400, }); } try { const result = await translationsCollection.get(lang); return new Response(JSON.stringify(result.content), { status: 200 }); } catch (error: any) { console.error('Error fetching translation:', error); return new Response(JSON.stringify({ message: `Translation Not Found: ${error.message}` }), { status: 500, }); } } export async function PUT(req: Request) { const { translationsCollection } = await connectToDatabase(); const { searchParams } = new URL(req.url); const lang = searchParams.get('lang'); const body = await req.json(); if (!lang || !body) { return new Response(JSON.stringify({ message: "Missing 'lang' parameter or request body" }), { status: 400, }); } try { await translationsCollection.upsert(lang, body); const updatedDoc = await translationsCollection.get(lang); return new Response(JSON.stringify(updatedDoc.content), { status: 200 }); } catch (error: any) { console.error('Error updating translation:', error); return new Response( JSON.stringify({ message: `Translation Update Failed: ${error.message}` }), { status: 500 } ); } }
已尝试的排查步骤
- 验证服务器运行状态及公网可达性
- 在生产服务器本地测试API路由,确认功能正常
- 检查路由文件路径:
src/app/api/translations/route.ts,路径无误 - 确认构建、部署过程无错误
- 删除
node_modules和.next文件夹,重新构建并重启应用
环境细节
- 使用Nginx作为反向代理(配置情况待确认)
- 公网URL启用HTTPS
核心问题
为何API路由在本地(开发环境、生产服务器本地)均正常,但通过公网URL访问时返回404?路由配置、反向代理或部署流程中是否存在常见问题?
可能的原因及解决方案
1. Nginx反向代理配置错误
这是最常见的原因,需确保Nginx正确将公网请求转发到Next.js服务的3000端口,且路径未被篡改:
- 检查Nginx配置中是否包含正确的转发规则,示例配置:
server { listen 443 ssl; server_name example.com; ssl_certificate /path/to/your/cert.pem; ssl_certificate_key /path/to/your/key.pem; location / { proxy_pass http://localhost:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } - 若单独配置了
location /api规则,需确保无路径重写错误,避免截断/api/translations这类子路径 - 修改配置后执行
nginx -s reload重启Nginx
2. 请求头传递不完整
Next.js的App Router路由匹配依赖Host和X-Forwarded-Proto等请求头:
- 确保Nginx配置中添加了
proxy_set_header Host $host;和proxy_set_header X-Forwarded-Proto $scheme;,否则Next.js可能无法正确识别请求路径
3. Next.js basePath配置冲突
检查next.config.js是否设置了basePath:
- 若存在如下配置,公网访问URL需包含对应前缀(如
https://example.com/myapp/api/translations):module.exports = { basePath: '/myapp', }; - 若无需前缀,删除该配置并重新构建部署
4. 生产构建缓存残留
即使删除过.next文件夹,仍可能存在构建缓存问题:
- 执行
next build --no-cache强制重新构建,确保生成的产物是最新的,之后重启服务
5. URL路径大小写不匹配
Next.js路由区分大小写,检查公网访问的URL路径是否完全匹配/api/translations(注意小写的api)
内容的提问来源于stack exchange,提问作者mryunus
相关产品推荐
相关产品推荐

