Next.js密码重置重定向报错:Unexpected token '<' 非有效JSON
问题原因
前端发送POST请求到API路由后,后端用NextResponse.redirect()直接返回重定向时,浏览器的fetch会自动跟进重定向,最终拿到的是目标页面的HTML内容,但你的前端代码仍在尝试将其解析为JSON,因此触发Unexpected token '<'的解析错误。
解决方案
不要让API路由直接返回重定向,改为返回JSON告知前端需要跳转,由前端主动执行页面跳转逻辑。
1. 修改后端API路由
将重定向逻辑改为返回包含跳转路径的JSON响应:
import { NextResponse } from 'next/server'; import { getUserByEmail } from '@/lib/db'; // 替换为你的用户查询逻辑 export async function POST(request) { const { email } = await request.json(); const user = await getUserByEmail(email); if (user && user.emailVerified) { // 执行发送密码重置邮件的逻辑 return NextResponse.json({ redirect: '/request-password-reset-message' }); } else { return NextResponse.json({ error: '邮箱不存在或未验证' }, { status: 400 }); } }
2. 修改前端请求处理逻辑
在表单提交后的请求回调中,判断返回的JSON是否包含跳转指令,主动执行页面跳转:
'use client'; import { useState } from 'react'; import { useRouter } from 'next/navigation'; // App Router 用法,Pages Router 用 next/router export default function PasswordResetRequest() { const [email, setEmail] = useState(''); const [error, setError] = useState(''); const router = useRouter(); async function handleSubmit(e) { e.preventDefault(); setError(''); try { const res = await fetch('/api/request-password-reset', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }), }); const data = await res.json(); if (data.redirect) { router.push(data.redirect); // 执行页面跳转 } else if (data.error) { setError(data.error); } } catch (err) { setError('请求失败,请稍后重试'); } } return ( <form onSubmit={handleSubmit}> <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="输入你的邮箱" required /> {error && <p style={{ color: 'red' }}>{error}</p>} <button type="submit">发送重置链接</button> </form> ); }
核心逻辑说明
前端fetch请求会自动跟随HTTP重定向,拿到重定向后的页面HTML,而你的代码原本期望解析JSON,所以报错。通过后端返回JSON指令、前端主动跳转的方式,可以避免这种解析冲突,同时保持前后端逻辑的清晰分离。
内容的提问来源于stack exchange,提问作者HKS
相关产品推荐
相关产品推荐

