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

Next.js 14 Server Actions修改Cookie报错问题求助

问题根源

你遇到的核心问题是:Server Action 不能在客户端代码中直接调用。虽然signout函数标注了'use server',但当你在axios的客户端响应拦截器里调用它时,这段代码会在浏览器环境执行——而next/headers提供的cookies API只能在服务端上下文(Server Action 或 Route Handler)中使用,客户端没有这个上下文,因此触发了错误提示。

解决方案

下面提供两种可行的修复方案,根据你的项目需求选择:

方案1:将登出逻辑改为 Route Handler

把登出的Cookie操作移到专门的Route Handler中,通过客户端发起HTTP请求触发服务端的Cookie修改:

  1. 创建Route Handler文件 app/api/signout/route.ts:
import { cookies } from 'next/headers';

export async function POST() {
  // 清除所有相关Cookie,确保path属性覆盖全局
  cookies.set('token', '', { maxAge: -1, path: '/' });
  cookies.set('refreshToken', '', { maxAge: -1, path: '/' });
  cookies.set('user', '', { maxAge: -1, path: '/' });

  // 返回成功响应,由客户端自行跳转
  return new Response(JSON.stringify({ success: true }), { status: 200 });
}
  1. 修改axios拦截器代码,替换直接调用signout为请求该Route:
Axios.interceptors.response.use(
    response => response,
    async (error: AxiosError<ApiResponseError>) => {
        if (error.status === 401 || error.response?.status === 401) {
            await fetch('/api/signout', { method: 'POST', credentials: 'include' });
            // 客户端手动跳转到登录页
            window.location.href = '/auth/signin';
        }

        return Promise.reject(error);
    },
);

方案2:通过客户端表单触发Server Action

如果坚持使用Server Action,需要通过客户端组件的表单来触发(Next.js要求Server Action必须通过表单或特定钩子触发,不能直接在客户端代码中调用):

  1. 在客户端组件中添加一个隐藏表单(比如在根布局或全局组件中引入):
'use client';

import { signout } from '@/utils/globalActions';

export function SignoutForm() {
  return (
    <form action={signout} id="global-signout-form" style={{ display: 'none' }}>
      <button type="submit"></button>
    </form>
  );
}
  1. 修改axios拦截器,通过提交表单触发登出:
Axios.interceptors.response.use(
    response => response,
    async (error: AxiosError<ApiResponseError>) => {
        if (error.status === 401 || error.response?.status === 401) {
            const form = document.getElementById('global-signout-form') as HTMLFormElement;
            form?.submit();
        }

        return Promise.reject(error);
    },
);
关键注意事项
  • 清除Cookie时要指定path: '/',避免因路径不匹配导致清除失败。
  • 使用Route Handler方案时,请求要加上credentials: 'include',确保携带Cookie信息。
  • Server Action仅支持通过表单提交、useActionState等官方指定方式触发,不能在客户端非交互逻辑中直接调用。

内容的提问来源于stack exchange,提问作者Léo Lhuile

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:33:09