Skip to content

NextJS中文文档 - Cookies

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

tsx
import { cookies } from 'next/headers'

export default async function Page() {
  const cookieStore = await cookies()
  const theme = cookieStore.get('theme')
  return '...'
}
js
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 中的值。
expires日期定义 cookie 将过期的确切日期。
maxAge数字设置 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:

tsx
import { cookies } from 'next/headers'

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

export default async function Page() {
  const cookieStore = await cookies()
  const theme = cookieStore.get('theme')
  return '...'
}

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

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>名称: {cookie.name}</p>
      <p>值: {cookie.value}</p>
    </div>
  ))
}
jsx
import { cookies } from 'next/headers'

export default async function Page() {
  const cookieStore = await cookies()
  return cookieStore.getAll().map((cookie) => (
    <div key={cookie.name}>
      <p>名称: {cookie.name}</p>
      <p>值: {cookie.value}</p>
    </div>
  ))
}

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

tsx
'use server'

import { cookies } from 'next/headers'

export async function create(data) {
  const cookieStore = await cookies()

  cookieStore.set('name', 'lee')
  // 或
  cookieStore.set('name', 'lee', { secure: true })
  // 或
  cookieStore.set({
    name: 'name',
    value: 'lee',
    httpOnly: true,
    path: '/',
  })
}
js
'use server'

import { cookies } from 'next/headers'

export async function create(data) {
  const cookieStore = await cookies()

  cookieStore.set('name', 'lee')
  // 或
  cookieStore.set('name', 'lee', { secure: true })
  // 或
  cookieStore.set({
    name: 'name',
    value: 'lee',
    httpOnly: true,
    path: '/',
  })
}

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

tsx
import { cookies } from 'next/headers'

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

export default async function Page() {
  const cookieStore = await cookies()
  const hasCookie = cookieStore.has('theme')
  return '...'
}

有三种方法可以删除 cookie。

使用 delete() 方法:

tsx
'use server'

import { cookies } from 'next/headers'

export async function delete(data) {
  (await cookies()).delete('name')
}
js
'use server'

import { cookies } from 'next/headers'

export async function delete(data) {
  (await cookies()).delete('name')
}

设置一个同名的空值新 cookie:

tsx
'use server'

import { cookies } from 'next/headers'

export async function delete(data) {
  (await cookies()).set('name', '')
}
js
'use server'

import { cookies } from 'next/headers'

export async function delete(data) {
  (await cookies()).set('name', '')
}

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

tsx
'use server'

import { cookies } from 'next/headers'

export async function delete(data) {
  (await cookies()).set('name', 'value', { maxAge: 0 })
}
js
'use server'

import { cookies } from 'next/headers'

export async function delete(data) {
  (await cookies()).set('name', 'value', { maxAge: 0 })
}

版本历史

版本变更
v15.0.RCcookies 现在是一个异步函数。提供了一个代码修改器
v13.0.0引入 cookies

🎉有任何问题,欢迎联系我

WeChat QR Code
WeChat
QQ QR Code
QQ

赣ICP备2023003243号