Skip to content

Bun 通過 Bun.CookieBun.CookieMap 提供用於處理 HTTP cookies 的原生 API。這些 API 提供快速、易於使用的方法來解析、生成和操作 HTTP 請求和響應中的 cookies。

CookieMap 類

Bun.CookieMap 提供類似 Map 的接口用於處理 cookies 集合。它實現了 Iterable 接口,允許你將其與 for...of 循環和其他迭代方法一起使用。

ts
// 空 cookie map
const cookies = new Bun.CookieMap();

// 從 cookie 字符串創建
const cookies1 = new Bun.CookieMap("name=value; foo=bar");

// 從對象創建
const cookies2 = new Bun.CookieMap({
  session: "abc123",
  theme: "dark",
});

// 從名稱/值對數組創建
const cookies3 = new Bun.CookieMap([
  ["session", "abc123"],
  ["theme", "dark"],
]);

在 HTTP 服務器中

在 Bun 的 HTTP 服務器中,請求對象上的 cookies 屬性(在 routes 中)是 CookieMap 的實例:

ts
const server = Bun.serve({
  routes: {
    "/": req => {
      // 訪問請求 cookies
      const cookies = req.cookies;

      // 獲取特定 cookie
      const sessionCookie = cookies.get("session");
      if (sessionCookie != null) {
        console.log(sessionCookie);
      }

      // 檢查 cookie 是否存在
      if (cookies.has("theme")) {
        // ...
      }

      // 設置 cookie,它將自動應用於響應
      cookies.set("visited", "true");

      return new Response("Hello");
    },
  },
});

console.log("服務器監聽於:" + server.url);

方法

get(name: string): string | null

按名稱檢索 cookie。如果 cookie 不存在則返回 null

ts
// 按名稱獲取
const cookie = cookies.get("session");

if (cookie != null) {
  console.log(cookie);
}

has(name: string): boolean

檢查是否存在具有給定名稱的 cookie。

ts
// 檢查 cookie 是否存在
if (cookies.has("session")) {
  // cookie 存在
}

set(name: string, value: string): void

set(options: CookieInit): void

添加或更新 map 中的 cookie。cookies 默認為 { path: "/", sameSite: "lax" }

ts
// 按名稱和值設置
cookies.set("session", "abc123");

// 使用選項對象設置
cookies.set({
  name: "theme",
  value: "dark",
  maxAge: 3600,
  secure: true,
});

// 使用 Cookie 實例設置
const cookie = new Bun.Cookie("visited", "true");
cookies.set(cookie);

delete(name: string): void

delete(options: CookieStoreDeleteOptions): void

從 map 中移除 cookie。當應用於 Response 時,這會添加一個值為空字符串且過期日期為過去的 cookie。只有當 domain 和 path 與創建 cookie 時相同,cookie 才會在瀏覽器上成功刪除。

ts
// 使用默認 domain 和 path 按名稱刪除
cookies.delete("session");

// 使用 domain/path 選項刪除
cookies.delete({
  name: "session",
  domain: "example.com",
  path: "/admin",
});

toJSON(): Record<string, string>

將 cookie map 轉換為可序列化格式。

ts
const json = cookies.toJSON();

toSetCookieHeaders(): string[]

返回 Set-Cookie 頭值的數組,可用於應用所有 cookie 更改。

使用 Bun.serve() 時,你不需要顯式調用此方法。對 req.cookies map 所做的任何更改都會自動應用於響應頭。此方法主要在使用其他 HTTP 服務器實現時很有用。

js
import { createServer } from "node:http";
import { CookieMap } from "bun";

const server = createServer((req, res) => {
  const cookieHeader = req.headers.cookie || "";
  const cookies = new CookieMap(cookieHeader);

  cookies.set("view-count", Number(cookies.get("view-count") || "0") + 1);
  cookies.delete("session");

  res.writeHead(200, {
    "Content-Type": "text/plain",
    "Set-Cookie": cookies.toSetCookieHeaders(),
  });
  res.end(`找到 ${cookies.size} 個 cookies`);
});

server.listen(3000, () => {
  console.log("服務器運行於 http://localhost:3000/");
});

迭代

CookieMap 提供多種迭代方法:

ts
// 迭代 [name, cookie] 條目
for (const [name, value] of cookies) {
  console.log(`${name}: ${value}`);
}

// 使用 entries()
for (const [name, value] of cookies.entries()) {
  console.log(`${name}: ${value}`);
}

// 使用 keys()
for (const name of cookies.keys()) {
  console.log(name);
}

// 使用 values()
for (const value of cookies.values()) {
  console.log(value);
}

// 使用 forEach
cookies.forEach((value, name) => {
  console.log(`${name}: ${value}`);
});

屬性

size: number

返回 map 中 cookies 的數量。

ts
console.log(cookies.size); // cookies 數量

Bun.Cookie 表示具有名稱、值和屬性的 HTTP cookie。

ts
import { Cookie } from "bun";

// 創建基本 cookie
const cookie = new Bun.Cookie("name", "value");

// 創建帶選項的 cookie
const secureSessionCookie = new Bun.Cookie("session", "abc123", {
  domain: "example.com",
  path: "/admin",
  expires: new Date(Date.now() + 86400000), // 1 天
  httpOnly: true,
  secure: true,
  sameSite: "strict",
});

// 從 cookie 字符串解析
const parsedCookie = new Bun.Cookie("name=value; Path=/; HttpOnly");

// 從選項對象創建
const objCookie = new Bun.Cookie({
  name: "theme",
  value: "dark",
  maxAge: 3600,
  secure: true,
});

構造函數

ts
// 使用名稱/值的基本構造函數
new Bun.Cookie(name: string, value: string);

// 使用名稱、值和選項的構造函數
new Bun.Cookie(name: string, value: string, options: CookieInit);

// 從 cookie 字符串構造函數
new Bun.Cookie(cookieString: string);

// 從 cookie 對象構造函數
new Bun.Cookie(options: CookieInit);

屬性

ts
cookie.name; // string - Cookie 名稱
cookie.value; // string - Cookie 值
cookie.domain; // string | null - 域名范圍(未指定時為 null)
cookie.path; // string - URL 路徑范圍(默認為 "/")
cookie.expires; // number | undefined - 過期時間戳(自紀元起的毫秒數)
cookie.secure; // boolean - 需要 HTTPS
cookie.sameSite; // "strict" | "lax" | "none" - SameSite 設置
cookie.partitioned; // boolean - cookie 是否分區(CHIPS)
cookie.maxAge; // number | undefined - 最大年齡(秒)
cookie.httpOnly; // boolean - 僅通過 HTTP 訪問(不可通過 JavaScript)

方法

isExpired(): boolean

檢查 cookie 是否已過期。

ts
// 已過期的 cookie(日期在過去)
const expiredCookie = new Bun.Cookie("name", "value", {
  expires: new Date(Date.now() - 1000),
});
console.log(expiredCookie.isExpired()); // true

// 有效 cookie(使用 maxAge 而不是 expires)
const validCookie = new Bun.Cookie("name", "value", {
  maxAge: 3600, // 1 小時(秒)
});
console.log(validCookie.isExpired()); // false

// 會話 cookie(無過期時間)
const sessionCookie = new Bun.Cookie("name", "value");
console.log(sessionCookie.isExpired()); // false

serialize(): string

toString(): string

返回適合 Set-Cookie 頭的 cookie 字符串表示形式。

ts
const cookie = new Bun.Cookie("session", "abc123", {
  domain: "example.com",
  path: "/admin",
  expires: new Date(Date.now() + 86400000),
  secure: true,
  httpOnly: true,
  sameSite: "strict",
});

console.log(cookie.serialize());
// => "session=abc123; Domain=example.com; Path=/admin; Expires=Sun, 19 Mar 2025 15:03:26 GMT; Secure; HttpOnly; SameSite=strict"
console.log(cookie.toString());
// => "session=abc123; Domain=example.com; Path=/admin; Expires=Sun, 19 Mar 2025 15:03:26 GMT; Secure; HttpOnly; SameSite=strict"

toJSON(): CookieInit

將 cookie 轉換為適合 JSON 序列化的普通對象。

ts
const cookie = new Bun.Cookie("session", "abc123", {
  secure: true,
  httpOnly: true,
});

const json = cookie.toJSON();
// => {
//   name: "session",
//   value: "abc123",
//   path: "/",
//   secure: true,
//   httpOnly: true,
//   sameSite: "lax",
//   partitioned: false
// }

// 可與 JSON.stringify 一起使用
const jsonString = JSON.stringify(cookie);

靜態方法

將 cookie 字符串解析為 Cookie 實例。

ts
const cookie = Bun.Cookie.parse("name=value; Path=/; Secure; SameSite=Lax");

console.log(cookie.name); // "name"
console.log(cookie.value); // "value"
console.log(cookie.path); // "/"
console.log(cookie.secure); // true
console.log(cookie.sameSite); // "lax"

用於創建 cookie 的工廠方法。

ts
const cookie = Bun.Cookie.from("session", "abc123", {
  httpOnly: true,
  secure: true,
  maxAge: 3600,
});

類型

ts
interface CookieInit {
  name?: string;
  value?: string;
  domain?: string;
  /** 默認為 '/'。要允許瀏覽器設置路徑,使用空字符串。 */
  path?: string;
  expires?: number | Date | string;
  secure?: boolean;
  /** 默認為 `lax`。 */
  sameSite?: CookieSameSite;
  httpOnly?: boolean;
  partitioned?: boolean;
  maxAge?: number;
}

interface CookieStoreDeleteOptions {
  name: string;
  domain?: string | null;
  path?: string;
}

interface CookieStoreGetOptions {
  name?: string;
  url?: string;
}

type CookieSameSite = "strict" | "lax" | "none";

class Cookie {
  constructor(name: string, value: string, options?: CookieInit);
  constructor(cookieString: string);
  constructor(cookieObject?: CookieInit);

  readonly name: string;
  value: string;
  domain?: string;
  path: string;
  expires?: Date;
  secure: boolean;
  sameSite: CookieSameSite;
  partitioned: boolean;
  maxAge?: number;
  httpOnly: boolean;

  isExpired(): boolean;

  serialize(): string;
  toString(): string;
  toJSON(): CookieInit;

  static parse(cookieString: string): Cookie;
  static from(name: string, value: string, options?: CookieInit): Cookie;
}

class CookieMap implements Iterable<[string, string]> {
  constructor(init?: string[][] | Record<string, string> | string);

  get(name: string): string | null;

  toSetCookieHeaders(): string[];

  has(name: string): boolean;
  set(name: string, value: string, options?: CookieInit): void;
  set(options: CookieInit): void;
  delete(name: string): void;
  delete(options: CookieStoreDeleteOptions): void;
  delete(name: string, options: Omit<CookieStoreDeleteOptions, "name">): void;
  toJSON(): Record<string, string>;

  readonly size: number;

  entries(): IterableIterator<[string, string]>;
  keys(): IterableIterator<string>;
  values(): IterableIterator<string>;
  forEach(callback: (value: string, key: string, map: CookieMap) => void): void;
  [Symbol.iterator](): IterableIterator<[string, string]>;
}

Bun學習網由www.bunjs.com.cn整理維護