Next.js 13 API路由中NextResponse.redirect()失效问题求助
问题分析与修复方案
你遇到的问题核心是:API路由返回的NextResponse.redirect()无法触发页面跳转,但数据创建逻辑正常。这是因为如果前端通过fetch/axios这类异步请求提交表单,浏览器不会自动处理异步请求返回的重定向响应——重定向只会在请求层面被跟随,不会触发页面级的跳转。
下面提供两种可行的修复方案:
方案一:使用表单默认提交行为
直接让表单以默认方式提交到API路由,此时浏览器会自动处理API返回的重定向响应,完成页面跳转。
修改app/page.tsx的表单代码:
export default function Home() { return ( <form action="/api/posts" method="POST"> <input type="text" name="title" placeholder="帖子标题" required /> <textarea name="content" placeholder="帖子内容" required></textarea> <button type="submit">发布帖子</button> </form> ); }
修改app/api/posts/route.ts的重定向逻辑:
注意使用303状态码,这是POST请求后重定向的标准状态码,告诉浏览器用GET请求目标页面,避免重复提交表单。
import { NextResponse } from 'next/server'; import prisma from '@/lib/prisma'; // 你的Prisma实例路径 export async function POST(request: Request) { const formData = await request.formData(); const title = formData.get('title') as string; const content = formData.get('content') as string; // 创建帖子 await prisma.post.create({ data: { title, content }, }); // 重定向到首页 return NextResponse.redirect(new URL('/', request.url), { status: 303 }); }
方案二:异步提交后前端手动跳转
如果需要保留前端表单验证、加载状态等逻辑,继续使用fetch异步提交,那么API只需返回成功响应,由前端在请求完成后手动触发跳转。
修改app/page.tsx的提交逻辑:
需要添加'use client'指令,因为要使用客户端路由或window对象。
'use client'; import { useRouter } from 'next/navigation'; export default function Home() { const router = useRouter(); const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); const formData = new FormData(e.currentTarget); try { const res = await fetch('/api/posts', { method: 'POST', body: formData, }); if (res.ok) { // 手动跳转到首页 router.push('/'); // 或者使用原生方式:window.location.href = '/' } } catch (err) { console.error('发布失败:', err); } }; return ( <form onSubmit={handleSubmit}> <input type="text" name="title" placeholder="帖子标题" required /> <textarea name="content" placeholder="帖子内容" required></textarea> <button type="submit">发布帖子</button> </form> ); }
修改app/api/posts/route.ts的响应逻辑:
import { NextResponse } from 'next/server'; import prisma from '@/lib/prisma'; export async function POST(request: Request) { const formData = await request.formData(); const title = formData.get('title') as string; const content = formData.get('content') as string; const newPost = await prisma.post.create({ data: { title, content }, }); // 返回创建成功的帖子数据 return NextResponse.json(newPost, { status: 201 }); }
内容的提问来源于stack exchange,提问作者GN Vageesh
相关产品推荐
相关产品推荐

