You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13服务端渲染中Axios withCredentials失效问题求助

问题根源

SSG(静态站点生成)是在项目构建阶段预渲染页面,这个过程完全没有用户的请求上下文——你的浏览器Cookie存在用户本地,构建服务器根本拿不到,自然没法携带给Laravel接口,导致401未授权。而且Laravel Sanctum的认证依赖用户会话Cookie,SSG阶段本身就不存在用户会话,所以这类需要用户登录状态的页面,本身就不适合用SSG。

下面给你两个可行的解决方案:


方案一:改用SSR(服务器端渲染)传递Cookie

在Next.js 13 App Router中,页面默认是服务器组件,可以直接获取当前请求的Cookie,手动传递给Laravel接口:

  1. 修改接口服务,支持接收Cookie参数:
// CategoryService.js
import axios from 'axios';

const baseURL = process.env.NEXT_PUBLIC_API_URL;

export const getAll = async (cookie) => {
  return axios.get(`${baseURL}/categories`, {
    headers: {
      // 手动把请求Cookie传给Laravel
      Cookie: cookie,
    },
    withCredentials: true,
  });
};
  1. 在页面组件中获取请求Cookie并调用接口:
// app/categories/page.js
import { headers } from 'next/headers';
import CategoryService from '@/services/CategoryService';
import CategoryView from '@/components/CategoryView';

export default async function Page() {
  // 从当前请求头中拿到Cookie
  const requestHeaders = headers();
  const cookie = requestHeaders.get('cookie');
  
  const response = await CategoryService.getAll(cookie);
  const categories = response.data.data;

  return <CategoryView categories={categories} />;
}

注:这个页面会自动变成SSR模式(每次用户请求时渲染),不再是SSG,这样才能拿到当前用户的会话Cookie。


方案二:静态页面+客户端请求数据

如果必须保留页面的静态特性,把需要认证的数据请求放到客户端组件中,利用浏览器环境自动携带Cookie:

  1. 创建客户端组件处理数据请求:
// app/categories/CategoryClient.js
'use client';

import { useEffect, useState } from 'react';
import CategoryService from '@/services/CategoryService';
import CategoryView from '@/components/CategoryView';

export default function CategoryClient() {
  const [categories, setCategories] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchData = async () => {
      try {
        // 客户端环境下,Axios的withCredentials会自动携带Cookie
        const response = await CategoryService.getAll();
        setCategories(response.data.data);
      } catch (err) {
        // 处理未授权,比如跳转到登录页
        if (err.response?.status === 401) {
          window.location.href = '/login';
        }
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, []);

  if (loading) return <div>加载中...</div>;

  return <CategoryView categories={categories} />;
}
  1. 在静态页面中引入这个客户端组件:
// app/categories/page.js
import CategoryClient from './CategoryClient';

export default function Page() {
  // 这里可以放静态内容,动态数据由客户端组件加载
  return <CategoryClient />;
}

额外注意事项

  • 确保Laravel的config/cors.php中,allowed_origins包含你的Next.js域名,supports_credentials设为true;
  • 如果Next.js和Laravel不在同一域名,要配置Laravel的Cookiedomain参数,保证Cookie可以跨域传递;
  • 永远不要尝试在SSG构建阶段获取用户专属数据——SSG生成的页面是所有用户共用的,不可能包含私有内容。

内容的提问来源于stack exchange,提问作者Juan Pablo B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:22:41