讲师中心 微信公众号
AI工具推荐 视频效率加速

在Next.js Server Actions中删除Cookie的正确姿势

秋浩君_2535

秋浩君_2535

发布时间:2025-11-24 11:20:49

|

508人浏览过

|

来源于php中文网

原创

在next.js server actions中删除cookie的正确姿势

本文深入探讨了在Next.js应用中,使用next/headers模块通过Server Actions删除Cookie时可能遇到的问题及其解决方案。核心在于理解Server Components与Server Actions的执行上下文差异,并展示了如何通过将Server Action传递给Client Component并在客户端触发来成功删除Cookie,同时强调了相关的安全注意事项。

理解Next.js中Cookie删除的限制

在Next.js的App Router架构中,操作HTTP响应头(包括设置或删除Cookie)是一个敏感操作,必须在特定的上下文中执行。根据Next.js的官方文档,cookies().set()和cookies().delete()等方法只能在Server Actions或Route Handlers中被调用。

当你在一个Server Component中定义一个带有"use server"指令的异步函数,并尝试直接在Server Component的渲染阶段调用它时,即使该函数本身是一个Server Action,其执行上下文也可能不被视为一个独立的Server Action调用。这意味着,直接在Server Component中调用cookies().delete()将导致运行时错误,提示“Cookies can only be modified in a Server Action or Route Handler”。

示例问题代码(错误用法):

// app/signout/page.js (Server Component)
import { cookies } from "next/headers";

export default async function Signout() {
    async function deleteTokens() {
       "use server" // 标记为Server Action

        cookies().delete('accessToken') // 在Server Component中直接调用,可能报错
    }

    // 在Server Component的渲染阶段直接调用
    await deleteTokens() 

    return (
        <></>
    );
}

上述代码的问题在于,尽管deleteTokens被标记为Server Action,但它是在Server Component的初始渲染流程中直接调用的,而不是作为由客户端触发的独立Server Action。Next.js要求Server Actions必须由客户端交互(例如表单提交、按钮点击或通过useEffect等生命周期钩子)显式触发,才能正确修改响应头。

正确的解决方案:通过客户端组件触发Server Action

为了解决这个问题,我们需要将Server Action的调用逻辑从Server Component的渲染阶段分离出来,并通过一个Client Component来触发它。这种模式确保了Server Action在正确的上下文中执行,从而允许其修改Cookie。

Web Accessibility (WCAG 2 AA))
Web Accessibility (WCAG 2 AA))

将 WCAG 2 AA 无障碍标准应用于设计系统、UI 组件和网页——通过可运行的验证器进行对比度计算,采用设计 token 模式使颜色天生可访问,设定排版和焦点状态规则,并提供语义检查清单。适用于构建或审查 UI。

下载

核心思路:

  1. 在Server Component中定义Server Action。
  2. 将这个Server Action作为prop传递给一个Client Component。
  3. 在Client Component中使用useEffect钩子来调用这个Server Action。

步骤一:在Server Component中定义并传递Server Action

首先,在你的Server Component(例如app/signout/page.js)中,像往常一样定义Server Action。然后,创建一个新的Client Component(例如SignOutAction.js),并将这个Server Action作为prop传递给它。

// app/signout/page.js (Server Component)
import { cookies } from "next/headers";
import SignOutAction from "./SignOutAction"; // 导入客户端组件

export default async function SignOut() {
  async function deleteTokens() {
    "use server"; // 明确标记为Server Action

    console.log("Attempting to delete accessToken cookie...");
    cookies().delete("accessToken"); // 在Server Action中删除Cookie
    console.log("accessToken cookie deletion attempted.");
  }

  // 将Server Action作为prop传递给Client Component
  return <SignOutAction deleteTokens={deleteTokens} />;
}

步骤二:在Client Component中触发Server Action

接下来,在Client Component(例如app/signout/SignOutAction.js)中,使用"use client"指令将其标记为客户端组件。然后,利用useEffect钩子在组件挂载后(或在特定依赖项变化时)调用传入的Server Action。

为了确保Server Action函数在useEffect的依赖数组中保持稳定,即使父组件重新渲染,也可以使用useRef来存储并访问该函数。这可以避免不必要的useEffect重新执行。

// app/signout/SignOutAction.js (Client Component)
"use client";

import { useEffect, useRef } from "react";

export default function SignOutAction({ deleteTokens }) {
  // 使用useRef来确保deleteTokens函数引用的稳定性
  const deleteTokensRef = useRef(deleteTokens);

  // 在每次渲染时更新ref,以防deleteTokens函数本身发生变化
  useEffect(() => {
    deleteTokensRef.current = deleteTokens;
  });

  // 组件挂载后调用Server Action
  useEffect(() => {
    console.log("Client component mounted, calling deleteTokens action...");
    deleteTokensRef.current();
  }, []); // 空依赖数组确保只在组件挂载时执行一次

  // 此组件不需要渲染任何UI
  return null;
}

通过这种方式,deleteTokens函数作为一个真正的Server Action,在Client Component挂载后被触发。此时,Next.js会将其视为一个由客户端发起的请求,从而允许它在服务器端正确地修改响应头并删除Cookie。

注意事项与最佳实践

  1. Server Action的调用上下文: 再次强调,Server Actions的强大之处在于它们可以在客户端被调用,并在服务器上执行。但它们不能仅仅因为被定义在Server Component中,就在Server Component的渲染流程中拥有修改HTTP头的权限。它们需要一个客户端触发点。
  2. 安全性:CSRF防护: 当执行如注销(Sign Out)这样的敏感操作时,即使是简单的Cookie删除,也应考虑CSRF(跨站请求伪造)攻击的风险。直接在页面加载时通过useEffect触发注销操作,可能会使你的应用容易受到CSRF攻击。
    • 风险: 恶意网站可能嵌入一个指向你应用注销端点的隐藏请求(例如,一个在Next.js Server Actions中删除Cookie的正确姿势标签或一个自动提交的表单),当用户访问恶意网站时,就会自动触发你应用的注销操作,而用户毫不知情。
    • 建议: 对于注销、删除账户等操作,最佳实践是要求用户进行明确的交互,例如点击一个“注销”按钮,并且通常会结合CSRF令牌进行防护。这确保了请求是用户有意发起的,而不是被恶意网站劫持。
    • 虽然本教程解决了Cookie删除的技术问题,但在实际生产环境中,请务必为敏感操作添加CSRF防护。
  3. Next.js版本: 本文的解决方案适用于Next.js 13.4.4及更高版本,特别是使用App Router的场景。
  4. 用户体验: 对于注销等操作,通常会伴随页面重定向或状态更新,以向用户明确表示操作已完成。在deleteTokens Server Action执行完毕后,你可以考虑使用redirect函数(来自next/navigation)将用户重定向到登录页或其他合适页面。

总结

在Next.js中正确删除Cookie的关键在于理解Server Components和Server Actions的执行模型。虽然Server Actions允许在服务器端执行代码,但它们必须由客户端显式触发才能执行涉及HTTP响应头修改的操作。通过将Server Action作为prop传递给Client Component,并在Client Component的useEffect中调用它,可以有效地解决在Server Component中直接删除Cookie时遇到的问题。同时,务必牢记在设计敏感操作时,考虑并实施适当的安全措施,如CSRF防护。

热门AI工具

更多
Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

相关专题

更多
cookie
cookie

Cookie 是一种在用户计算机上存储小型文本文件的技术,用于在用户与网站进行交互时收集和存储有关用户的信息。当用户访问一个网站时,网站会将一个包含特定信息的 Cookie 文件发送到用户的浏览器,浏览器会将该 Cookie 存储在用户的计算机上。之后,当用户再次访问该网站时,浏览器会向服务器发送 Cookie,服务器可以根据 Cookie 中的信息来识别用户、跟踪用户行为等。

12159

2023.06.30

document.cookie获取不到怎么解决
document.cookie获取不到怎么解决

document.cookie获取不到的解决办法:1、浏览器的隐私设置;2、Same-origin policy;3、HTTPOnly Cookie;4、JavaScript代码错误;5、Cookie不存在或过期等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1186

2023.11.23

阻止所有cookie什么意思
阻止所有cookie什么意思

阻止所有cookie意味着在浏览器中禁止接受和存储网站发送的cookie。阻止所有cookie可能会影响许多网站的使用体验,因为许多网站使用cookie来提供个性化服务、存储用户信息或跟踪用户行为。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

824

2024.02.23

cookie与session的区别
cookie与session的区别

本专题整合了cookie与session的区别和使用方法等相关内容,阅读专题下面的文章了解更详细的内容。

1926

2025.08.19

数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

3151

2023.11.13

drop和delete的区别
drop和delete的区别

drop和delete的区别:1、功能与用途;2、操作对象;3、可逆性;4、空间释放;5、执行速度与效率;6、与其他命令的交互;7、影响的持久性;8、语法和执行;9、触发器与约束;10、事务处理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

965

2023.12.29

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

4516

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1375

2023.07.28

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

60

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 12.3万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn