Next.js集成Auth.js时API路由fetch请求失败排查求助
问题排查与解决方案
核心原因分析
你遇到的Unexpected token '<'错误,本质是API路由返回了HTML内容(大概率是登录页面)而非预期的JSON。直接在浏览器访问API正常是因为浏览器自动携带了登录态Cookie,但fetch请求默认不会携带凭证,导致API路由未识别到用户会话,被中间件重定向到登录页。
具体修复步骤
1. 给fetch请求添加凭证参数
修改app/projects/page.js中的fetch调用,添加credentials: 'same-origin'(同域请求推荐),确保请求携带登录态Cookie:
async function getProjects() { try { console.log("FETCHING DOCUMENTS"); const res = await fetch("/api/Projects", { // 换成相对路径更稳妥 cache: "no-store", credentials: "same-origin" // 关键:携带Cookie }); if (!res.ok) { throw new Error(`HTTP error! status: ${res.status}`); } console.log(res); return res.json(); } catch (error) { console.log(error); } };
注:用相对路径/api/Projects代替绝对路径,避免环境切换时的域名问题。
2. 完善API路由的会话校验与错误处理
当前API路由未校验session是否存在,直接访问session.user.id会导致未认证时抛出错误,且错误返回是纯文本而非JSON,进一步加剧解析问题。修改api/Projects/route.js:
import { connectDB } from "../../../utils/database"; import { NextResponse } from "next/server"; import Project from "../../(models)/Project"; import { getServerSession } from "next-auth"; import { options } from "../../api/auth/[...nextauth]/options"; export const GET = async (req) => { const session = await getServerSession(options); // 先校验会话是否存在 if (!session || !session.user?.id) { return new NextResponse(JSON.stringify({ error: "未授权访问" }), { status: 401, headers: { "Content-Type": "application/json" } }); } try { await connectDB(); const fetchedProjects = await Project.find({ userID: session.user.id, }).exec(); return new NextResponse(JSON.stringify(fetchedProjects), { status: 200, headers: { "Content-Type": "application/json" } // 显式指定JSON类型 }); } catch (error) { return new NextResponse(JSON.stringify({ error: "数据获取失败", details: error.message }), { status: 500, headers: { "Content-Type": "application/json" } }); } };
关键改进:
- 提前校验
session,未授权时返回401 JSON响应 - 所有响应显式指定
Content-Type: application/json - 错误返回用JSON格式,避免纯文本导致的解析失败
3. 检查Next.js中间件的匹配规则
确保中间件没有错误拦截/api/Projects请求,或者确认中间件对API路由的认证逻辑正确。比如中间件配置中,是否正确允许已认证用户访问该API,未认证用户是否会被重定向(这正是导致HTML返回的原因)。
如果中间件是基于路径匹配,确保/api/Projects在受保护路径内,且重定向逻辑仅在未认证时触发——但前提是fetch请求携带了Cookie,否则中间件会认为用户未登录并重定向。
验证步骤
- 重启开发服务器,确保代码修改生效
- 登录后访问
/projects页面,查看控制台是否正常打印项目数据 - 如果仍有问题,打开浏览器DevTools的Network面板,查看
/api/Projects请求的响应内容:- 若响应是登录页面HTML,说明
fetch仍未携带Cookie,或中间件配置有误 - 若响应是401 JSON,说明会话校验逻辑生效,需检查登录态是否有效
- 若响应是登录页面HTML,说明
内容的提问来源于stack exchange,提问作者LL1997
相关产品推荐
相关产品推荐

