Bun предоставляет нативные API для работы с HTTP cookies через Bun.Cookie и Bun.CookieMap. Эти API предлагают быстрые, простые в использовании методы для разбора, генерации и манипуляции cookies в HTTP-запросах и ответах.
Класс CookieMap
Bun.CookieMap предоставляет интерфейс, подобный Map, для работы с коллекциями cookies. Он реализует интерфейс Iterable, позволяя использовать его с циклами for...of и другими методами итерации.
// Пустая карта cookies
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"],
]);2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
В HTTP-серверах
В HTTP-сервере Bun свойство cookies на объекте запроса (в routes) является экземпляром CookieMap:
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);2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Методы
get(name: string): string | null
Получает cookie по имени. Возвращает null, если cookie не существует.
// Получить по имени
const cookie = cookies.get("session");
if (cookie != null) {
console.log(cookie);
}2
3
4
5
6
has(name: string): boolean
Проверяет, существует ли cookie с данным именем.
// Проверить, существует ли cookie
if (cookies.has("session")) {
// Cookie существует
}2
3
4
set(name: string, value: string): void
set(options: CookieInit): void
set(cookie: Cookie): void
Добавляет или обновляет cookie в карте. Cookies по умолчанию имеют { path: "/", sameSite: "lax" }.
// Установить по имени и значению
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);2
3
4
5
6
7
8
9
10
11
12
13
14
delete(name: string): void
delete(options: CookieStoreDeleteOptions): void
Удаляет cookie из карты. При применении к Response это добавляет cookie с пустым значением и датой истечения в прошлом. Cookie будет успешно удалена в браузере только если домен и путь совпадают с теми, которые были при создании cookie.
// Удалить по имени с использованием домена и пути по умолчанию.
cookies.delete("session");
// Удалить с опциями домена/пути.
cookies.delete({
name: "session",
domain: "example.com",
path: "/admin",
});2
3
4
5
6
7
8
9
toJSON(): Record<string, string>
Преобразует карту cookies в сериализуемый формат.
const json = cookies.toJSON();toSetCookieHeaders(): string[]
Возвращает массив значений для заголовков Set-Cookie, которые могут быть использованы для применения всех изменений cookies.
При использовании Bun.serve() вам не нужно вызывать этот метод явно. Любые изменения, внесённые в карту req.cookies, автоматически применяются к заголовкам ответа. Этот метод в первую очередь полезен при работе с другими реализациями HTTP-серверов.
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/");
});2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Итерация
CookieMap предоставляет несколько методов для итерации:
// Итерация по записям [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}`);
});2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Свойства
size: number
Возвращает количество cookies в карте.
console.log(cookies.size); // Количество cookiesКласс Cookie
Bun.Cookie представляет HTTP cookie с его именем, значением и атрибутами.
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,
});2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Конструкторы
// Базовый конструктор с именем/значением
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);2
3
4
5
6
7
8
9
10
11
Свойства
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)2
3
4
5
6
7
8
9
10
Методы
isExpired(): boolean
Проверяет, истекла ли cookie.
// Истёкшая 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()); // false2
3
4
5
6
7
8
9
10
11
12
13
14
15
serialize(): string
toString(): string
Возвращает строковое представление cookie, подходящее для заголовка Set-Cookie.
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"2
3
4
5
6
7
8
9
10
11
12
13
toJSON(): CookieInit
Преобразует cookie в простой объект, подходящий для JSON-сериализации.
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);2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Статические методы
Cookie.parse(cookieString: string): Cookie
Разбирает строку cookie в экземпляр Cookie.
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"2
3
4
5
6
7
Cookie.from(name: string, value: string, options?: CookieInit): Cookie
Фабричный метод для создания cookie.
const cookie = Bun.Cookie.from("session", "abc123", {
httpOnly: true,
secure: true,
maxAge: 3600,
});2
3
4
5
Типы
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]>;
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77