跳到內容

cookies

cookies 是一個非同步函數,可讓你在伺服器元件中讀取 HTTP 輸入請求 cookies,以及在伺服器行為路由處理器中讀取/寫入輸出請求 cookies。

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()物件陣列傳回所有名稱符合的 cookies 清單。
has('name')布林值接受 cookie 名稱,並根據 cookie 是否存在傳回布林值。
set(name, value, options)-接受 cookie 名稱、值和選項,並設定輸出請求 cookie。
delete(name)-接受 cookie 名稱並刪除 cookie。
clear()-刪除所有 cookies。
toString()字串傳回 cookies 的字串表示形式。

選項

設定 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 函數來存取 cookies。
    • 在版本 14 和更早版本中,cookies 是一個同步函數。為了協助向後相容,你仍然可以在 Next.js 15 中同步存取它,但此行為在未來將會被棄用。
  • cookies 是一個 動態 API,其傳回值無法事先得知。在版面配置或頁面中使用它會使路由選擇加入動態渲染
  • .delete 方法只能在以下情況下呼叫
    • 伺服器行為路由處理器中。
    • 如果它屬於與呼叫 .set 相同的網域。對於萬用字元網域,特定子網域必須完全相符。此外,程式碼必須以與你要刪除的 cookie 相同的協定 (HTTP 或 HTTPS) 執行。
  • HTTP 不允許在串流開始後設定 cookies,因此你必須在伺服器行為路由處理器中使用 .set

在伺服器元件中使用 cookies 時,務必了解 cookies 本質上是一種客戶端儲存機制

  • 讀取 cookies 在伺服器元件中有效,因為你正在存取客戶端瀏覽器在 HTTP 請求標頭中傳送給伺服器的 cookie 資料。
  • 設定 cookies 無法直接在伺服器元件中完成,即使使用路由處理器或伺服器行為也是如此。這是因為 cookies 實際上是由瀏覽器而非伺服器儲存。

伺服器只能傳送指示 (透過 Set-Cookie 標頭) 告知瀏覽器儲存 cookies - 實際儲存發生在客戶端。這就是為什麼修改狀態的 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 '...'
}

取得所有 cookies

你可以使用 (await cookies()).getAll() 方法來取得所有名稱符合的 cookies。如果未指定 name,則會傳回所有可用的 cookies。

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 '...'
}

刪除 cookies

有三種方法可以刪除 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