Next.js app路由文件上传API返回404问题排查求助
Next.js App Router 文件上传API 404错误解决方案
问题根源分析
- API路由写法不兼容App Router:旧版Pages Router用
NextApiRequest/NextApiResponse并导出default handler,但App Router要求导出对应HTTP方法的函数(如POST),且使用Web标准的Request/Response对象。 - 请求路径错误:
app/api/route.ts对应的访问路径是/api,而非你代码中的/api/route,这是404的直接原因。 - Form Data处理逻辑不适配:App Router无法直接使用Pages Router的
parseForm(req)方式,需要基于Web标准的Request对象调整。
修正后的代码实现
1. API路由(app/api/route.ts)
import { NextResponse } from 'next/server'; // 替换为你的Formidable相关导入路径 import { parseForm, FormidableError } from './formidable-config'; import type { IncomingMessage } from 'http'; import { Readable } from 'stream'; export async function POST(request: Request) { console.log("START"); try { // 将Web Request转换为Node.js IncomingMessage以适配Formidable const nodeReq = Readable.from(await request.arrayBuffer()) as unknown as IncomingMessage; nodeReq.headers = Object.fromEntries(request.headers.entries()); nodeReq.method = request.method; const { fields, files } = await parseForm(nodeReq); const file = files.media.toString(); const url = file; // 替换为你的实际文件处理逻辑 return NextResponse.json( { data: { url }, error: null }, { status: 200 } ); } catch (e) { if (e instanceof FormidableError) { return NextResponse.json( { data: null, error: e.message }, { status: (e as any).httpCode || 400 } ); } else { console.error(e); return NextResponse.json( { data: null, error: "Internal Server Error" }, { status: 500 } ); } } } // 指定Node.js运行时,确保Formidable能正常工作 export const config = { runtime: 'nodejs', };
2. 前端上传函数(SingleFileUploadForm.tsx)
const onUploadFile = async (e: React.MouseEvent<HTMLButtonElement>) => { e.preventDefault(); console.log("Upload..."); if (!file) return; try { const formData = new FormData(); formData.append("media", file); // 修正请求路径为/api const res = await fetch("/api", { method: "POST", body: formData, }); const { data, error }: { data: { url: string } | null; error: string | null; } = await res.json(); if (error || !data) { alert(error || "Sorry! Something went wrong."); return; } console.log("Files was uploaded successfully: ", data); } catch (e) { console.error(e); alert("Something went wrong."); } };
验证步骤
- 重启Next.js开发服务器,确保路由变更生效
- 确认文件结构:API路由必须是
app/api/route.ts(若路径为app/api/route/route.ts,才对应/api/route) - 测试上传,查看服务器控制台是否输出
START,验证请求是否成功
内容的提问来源于stack exchange,提问作者Tellimi
相关产品推荐
相关产品推荐

