跳到内容

cookies

cookies 是一个异步函数,允许你在服务器组件中读取 HTTP 请求的传入 cookie,并在服务器操作路由处理器中读取/写入传出请求 cookie。

app/page.tsx
import { cookies } from 'next/headers'
 
export default async function Page() {
  const cookieStore = await cookies()
  const theme = cookieStore.get('theme')
  return '...'
}

参考

方法

以下方法可用

方法返回类型描述
get('name')对象接受一个 cookie 名称,并返回一个包含名称和值的对象。
getAll()对象数组返回具有匹配名称的所有 cookie 的列表。
has('name')布尔值接受一个 cookie 名称,并返回一个布尔值,指示 cookie 是否存在。
set(name, value, options)-接受 cookie 名称、值和选项,并设置传出请求 cookie。
delete(name)-接受一个 cookie 名称并删除该 cookie。
clear()-删除所有 cookie。
toString()字符串返回 cookie 的字符串表示形式。

选项

设置 cookie 时,支持来自 options 对象的以下属性

选项类型描述
name字符串指定 cookie 的名称。
value字符串指定要存储在 cookie 中的值。
expiresDate定义 cookie 过期的确切日期。
maxAgeNumber以秒为单位设置 cookie 的生命周期。
domain字符串指定 cookie 可用的域。
path字符串,默认值:'/'将 cookie 的作用域限制为域内的特定路径。
secure布尔值确保 cookie 仅通过 HTTPS 连接发送,以增加安全性。
httpOnly布尔值将 cookie 限制为 HTTP 请求,防止客户端访问。
sameSite布尔值, 'lax', 'strict', 'none'控制 cookie 的跨站点请求行为。
priority字符串 ("low", "medium", "high")指定 cookie 的优先级
encode('value')函数指定一个函数,该函数将用于编码 cookie 的值。
partitioned布尔值指示 cookie 是否已分区

唯一具有默认值的选项是 path

要了解有关这些选项的更多信息,请参阅 MDN 文档

须知

  • cookies 是一个异步函数,返回一个 Promise。你必须使用 async/await 或 React 的 use 函数来访问 cookie。
    • 在版本 14 及更早版本中,cookies 是一个同步函数。为了帮助向后兼容,你仍然可以在 Next.js 15 中同步访问它,但此行为将在未来版本中弃用。
  • cookies 是一个动态 API,其返回值无法提前知晓。在布局或页面中使用它会将路由选择加入动态渲染
  • .delete 方法只能在以下情况下调用
    • 服务器操作路由处理器中。
    • 如果它属于与调用 .set 的域相同的域。对于通配符域,特定子域必须完全匹配。此外,代码必须在与你要删除的 cookie 相同的协议(HTTP 或 HTTPS)上执行。
  • HTTP 不允许在流式传输开始后设置 cookie,因此你必须在服务器操作路由处理器中使用 .set

在服务器组件中使用 cookie 时,重要的是要理解 cookie 本质上是一种客户端存储机制

  • 读取 cookie 在服务器组件中有效,因为你正在访问客户端浏览器在 HTTP 请求头中发送到服务器的 cookie 数据。
  • 设置 cookie 无法在服务器组件中直接完成,即使使用路由处理器或服务器操作也是如此。这是因为 cookie 实际上是由浏览器而不是服务器存储的。

服务器只能发送指令(通过 Set-Cookie 标头)来告知浏览器存储 cookie - 实际存储发生在客户端。这就是为什么修改状态的 cookie 操作(.set.delete.clear)必须在路由处理器或服务器操作中执行,在这些地方可以正确设置响应标头。

示例

你可以使用 (await cookies()).get('name') 方法来获取单个 cookie

app/page.tsx
import { cookies } from 'next/headers'
 
export default async function Page() {
  const cookieStore = await cookies()
  const theme = cookieStore.get('theme')
  return '...'
}

获取所有 cookie

你可以使用 (await cookies()).getAll() 方法来获取所有具有匹配名称的 cookie。如果未指定 name,它将返回所有可用的 cookie。

app/page.tsx
import { cookies } from 'next/headers'
 
export default async function Page() {
  const cookieStore = await cookies()
  return cookieStore.getAll().map((cookie) => (
    <div key={cookie.name}>
      <p>Name: {cookie.name}</p>
      <p>Value: {cookie.value}</p>
    </div>
  ))
}

你可以在服务器操作路由处理器中使用 (await cookies()).set(name, value, options) 方法来设置 cookie。options 对象是可选的。

app/actions.ts
'use server'
 
import { cookies } from 'next/headers'
 
export async function create(data) {
  const cookieStore = await cookies()
 
  cookieStore.set('name', 'lee')
  // or
  cookieStore.set('name', 'lee', { secure: true })
  // or
  cookieStore.set({
    name: 'name',
    value: 'lee',
    httpOnly: true,
    path: '/',
  })
}

你可以使用 (await cookies()).has(name) 方法来检查 cookie 是否存在

app/page.ts
import { cookies } from 'next/headers'
 
export default async function Page() {
  const cookieStore = await cookies()
  const hasCookie = cookieStore.has('theme')
  return '...'
}

删除 cookie

有三种方法可以删除 cookie。

使用 delete() 方法

app/actions.ts
'use server'
 
import { cookies } from 'next/headers'
 
export async function delete(data) {
  (await cookies()).delete('name')
}

设置一个同名的新 cookie 并赋予空值

app/actions.ts
'use server'
 
import { cookies } from 'next/headers'
 
export async function delete(data) {
  (await cookies()).set('name', '')
}

maxAge 设置为 0 将立即过期 cookie。maxAge 接受以秒为单位的值。

app/actions.ts
'use server'
 
import { cookies } from 'next/headers'
 
export async function delete(data) {
  (await cookies()).set('name', 'value', { maxAge: 0 })
}

版本历史

版本变更
v15.0.0-RCcookies 现在是一个异步函数。提供了一个 codemod
v13.0.0引入了 cookies