Next.js响应头重定向问题:按钮点击后无法跳转仅返回307
问题:Fetch调用Next.js API路由后无法通过响应头重定向,但直接访问正常
问题详情
- 需求目标:点击页面按钮触发fetch请求到API路由,期望路由设置Cookie后,通过响应头重定向至
/about页面 - 异常现象:直接在浏览器地址栏访问该API路由时,Cookie设置和页面跳转都正常;但通过按钮触发fetch调用时,Cookie成功设置,页面却不跳转,仅返回307状态码
- 环境:API与前端运行在同一Next.js服务器中,希望通过响应头实现重定向,不想使用Next.js router方案
代码示例
home.tsx(前端页面)
'use client'; export default function Home() { const handleSet = () => { (async () => { await fetch('http://localhost:3000/api/test-path'); })(); }; return ( <main className="min-h-screen"> <p>Home page</p> <button className="btn btn-primary" onClick={handleSet}> Set cookies </button> </main> ); }
route.ts(API路由)
import { NextRequest, NextResponse } from 'next/server'; export async function GET(request: NextRequest) { const response = NextResponse.redirect(new URL('/about', new URL(request.url).origin)); response.cookies.set({ name: 'theme', value: 'dark', expires: new Date(2023, new Date().getMonth(), new Date().getDate(), new Date().getHours() + 3, 0, 0), path: '/', secure: true, httpOnly: true, sameSite: 'strict' }); return response; }
问题原因
fetch属于后台AJAX请求,和直接在地址栏访问的页面导航请求逻辑完全不同:
- 页面导航请求:浏览器会自动识别响应头中的
Location字段,直接触发页面跳转 - AJAX请求:浏览器只会在后台跟随重定向获取响应内容,不会主动触发页面级的跳转,所以你只能拿到307状态码,页面不会有任何变化
解决方案
在fetch请求的响应中手动检测重定向状态码,然后通过window.location.href触发页面跳转,修改后的home.tsx代码如下:
'use client'; export default function Home() { const handleSet = () => { (async () => { const res = await fetch('http://localhost:3000/api/test-path'); // 检测常见的重定向状态码 if ([301, 302, 307, 308].includes(res.status)) { const redirectUrl = res.headers.get('Location'); if (redirectUrl) { window.location.href = redirectUrl; } } })(); }; return ( <main className="min-h-screen"> <p>Home page</p> <button className="btn btn-primary" onClick={handleSet}> Set cookies </button> </main> ); }
补充说明
你的API路由代码完全正常,Cookie设置逻辑没有问题,只是AJAX请求的特性导致浏览器不会自动跳转,必须手动处理。
内容的提问来源于stack exchange,提问作者Kishore Kumer
相关产品推荐
相关产品推荐

