Deno реализует многие стандартные API веб-платформы, доступные в современных браузерах. Это значит, что если вы разрабатывали приложения для веба, то, скорее всего, уже знакомы со многими API Deno. Изучая Deno, вы также углубляете свои знания о веб-платформе.
В этом разделе представлена подробная документация по всем поддерживаемым в Deno API веб-платформы. Вы можете просмотреть все символы, чтобы увидеть полный список или выполнить поиск по категориям. Нажмите на любую функцию или интерфейс, чтобы посмотреть подробную документацию с примерами.
Основные API веб-платформы
Deno поддерживает широкий набор стандартных веб-API:
Сеть и коммуникация
-
fetch— HTTP-запросы в соответствии со спецификацией WHATWG Fetch - WebSocket — дуплексная связь через TCP
- События, отправленные сервером — потоковая передача событий от сервера клиенту
- BroadcastChannel — обмен сообщениями между контекстами
Хранение и состояние
- Веб-хранилище — API localStorage и sessionStorage
- Cache API — интерфейс кэширования HTTP-ответов
- IndexedDB — хранилище базы данных на стороне клиента
Воркеры и параллелизм
- Веб-воркеры — выполнение в фоновых потоках
- SharedArrayBuffer — общая память между воркерами
Потоки и данные
- Streams API — комбинируемые интерфейсы потоковой передачи данных
- Сжатие — встроенное сжатие gzip/deflate
- File API — работа с файлами и объектами Blob
События и DOM
- Event API — стандартные шаблоны обработки событий
- CustomEvent — создание и отправка пользовательских событий
- EventTarget — управление обработчиками событий
Кодирование и криптография
- TextEncoder/TextDecoder — кодирование и декодирование текста UTF-8
- Web Crypto — криптографические операции
- URL API — разбор и обработка URL
Таймеры и производительность
- Performance API — высокоточное измерение времени
- Таймеры — setTimeout, setInterval и setImmediate
Структурированное клонирование и передаваемые объекты
Deno поддерживает structuredClone() и postMessage() для клонирования и передачи объектов между контекстами (например, между главным потоком и веб-воркерами).
Сериализуемые типы
Эти типы можно клонировать с помощью structuredClone() и передавать через postMessage():
| Тип | Примечания |
|---|---|
| Примитивы |
string, number, boolean, null, undefined, bigint
|
Array, Object, Map, Set
| Включая вложенные структуры и циклические ссылки |
Date, RegExp
| |
ArrayBuffer, TypedArray, DataView
| По умолчанию копируются, либо передаются (см. ниже) |
Типы Error |
Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError
|
Blob | Требуется Deno 2.8 или новее |
File | Требуется Deno 2.8 или новее |
DOMException | |
CryptoKey |
Передаваемые типы
Эти типы можно передавать (а не копировать) с помощью параметра transfer в structuredClone() или списка transfer в postMessage(). После передачи исходный объект становится непригодным для использования:
| Тип | Примечания |
|---|---|
ArrayBuffer | Перемещает резервную память получателю |
MessagePort | Передаёт порт в другой контекст |
ReadableStream | Передаёт поток в другой контекст |
WritableStream | Передаёт поток в другой контекст |
TransformStream | Передаёт поток в другой контекст |
// Clone a Blob
const blob = new Blob(["hello"], { type: "text/plain" });
const cloned = structuredClone(blob);
console.log(await cloned.text()); // "hello"
// Transfer an ArrayBuffer through a MessageChannel
const buffer = new ArrayBuffer(1024);
const ch = new MessageChannel();
ch.port1.postMessage(buffer, [buffer]);
// buffer.byteLength is now 0 (transferred)
Ключевые преимущества
- Соответствие стандартам: API соответствуют спецификациям WHATWG и W3C
- Кроссплатформенность: код работает одинаково в Deno, браузерах и других средах выполнения
- Без полифилов: нативные реализации обеспечивают оптимальную производительность
- Готовность к будущему: основано на развивающихся веб-стандартах
Примеры использования
Выполнение HTTP-запросов
const response = await fetch("https://api.github.com/users/denoland");
const data = await response.json();
console.log(data);
Использование веб-воркеров
// main.js
const worker = new Worker(import.meta.resolve("./worker.js"), {
type: "module",
});
worker.postMessage({ task: "process_data", data: [1, 2, 3] });
worker.onmessage = (e) => console.log("Result:", e.data);
// worker.js
self.onmessage = (e) => {
const { task, data } = e.data;
const result = data.map((x) => x * 2);
self.postMessage(result);
};
Локальное хранилище
// Persist data across sessions
localStorage.setItem("user_preference", "dark_mode");
const preference = localStorage.getItem("user_preference");
Примечания о совместимости
Чтобы проверить, доступен ли API веб-платформы в Deno, обратитесь к документации по интерфейсу на сайте MDN и к таблице совместимости с браузерами.
Большинство API реализовано в соответствии со спецификациями, с некоторыми адаптациями Deno для серверных сред. Примечательные отличия описаны ниже.
fetch
API fetch можно использовать для выполнения HTTP-запросов. Он реализован в соответствии со спецификацией WHATWG fetch.
Отклонения от спецификации
- В пользовательском агенте Deno нет хранилища файлов cookie. Поэтому заголовок
set-cookieответа не обрабатывается и не удаляется из видимых заголовков ответа. - Deno не соблюдает политику одного источника, поскольку пользовательский агент Deno в настоящее время не оперирует понятием источников и не имеет хранилища файлов cookie. Это значит, что Deno не требуется защищать аутентифицированные данные от утечки между источниками. Поэтому Deno не реализует следующие разделы спецификации WHATWG
fetch:- Раздел
3.1. 'Origin' header. - Раздел
3.2. CORS protocol. - Раздел
3.5. CORB. - Раздел
3.6. 'Cross-Origin-Resource-Policy' header. -
Atomic HTTP redirect handling. - Тип ответа
opaqueredirect.
- Раздел
- Запрос
fetchс режимомredirect, равнымmanual, возвращает ответbasic, а не ответopaqueredirect. - В спецификации расплывчато описано, как следует обрабатывать URL-адреса
file:. Firefox — единственный распространённый браузер, в котором реализована загрузка URL-адресовfile:, и даже там она по умолчанию не работает. Начиная с Deno 1.16, Deno поддерживает загрузку локальных файлов. Подробности см. в следующем разделе. - Защита заголовков
requestиresponseреализована, но, в отличие от браузеров, ограничений на допустимые имена заголовков нет. - Свойства
referrer,referrerPolicy,mode,credentials,cache,integrity,keepaliveиwindow, а также соответствующее им поведение вRequestInitне реализованы. Соответствующие поля отсутствуют в объектеRequest. - Поддерживается потоковая передача тела запроса (для HTTP/1.1 и HTTP/2). В отличие от текущего предложения по Fetch, реализация поддерживает двунаправленную потоковую передачу.
- Заголовок
set-cookieне объединяется при переборе с помощью итератораheaders. Это поведение в процессе стандартизации.
Загрузка локальных файлов
Deno поддерживает загрузку URL-адресов file:. Это упрощает написание кода, использующего один и тот же путь выполнения как на сервере, так и локально, а также позволяет легче создавать код, работающий и с Deno CLI, и с Deno Deploy.
Deno поддерживает только абсолютные URL-адреса файлов, поэтому fetch("./some.json") работать не будет. Однако следует отметить, что если указан --location, то относительные URL-адреса используют --location в качестве базового адреса, но URL-адрес file: нельзя передать в качестве --location.
Чтобы загрузить ресурс относительно текущего модуля — независимо от того, локальный модуль или удалённый, — используйте import.meta.url в качестве базового адреса. Например:
const response = await fetch(new URL("./config.json", import.meta.url));
const config = await response.json();
Примечания о загрузке локальных файлов:
- Для чтения ресурсов применяются разрешения, поэтому для чтения локального файла требуется соответствующее разрешение
--allow-read. - Локальная загрузка поддерживает только метод
GET; при использовании любого другого метода промис будет отклонён. - Если файл не существует, промис просто отклоняется с неопределённой ошибкой
TypeError. Это сделано для предотвращения потенциальных атак по сбору данных об окружении. - В ответе не устанавливаются заголовки. Поэтому потребитель должен самостоятельно определять такие параметры, как тип или длина содержимого.
- Тела ответов передаются потоками со стороны Rust, поэтому большие файлы доступны частями, а передачу можно отменить.
CustomEvent и EventTarget
DOM Event API можно использовать для отправки событий приложения и прослушивания этих событий. Он реализован в соответствии со спецификацией WHATWG DOM.
Отклонения Event API
- События не всплывают, поскольку в Deno нет иерархии DOM, а значит, нет дерева, по которому события могли бы всплывать или перехватываться.
-
Свойству
timeStampвсегда присваивается значение0.
Определения типов
Определения TypeScript для реализованных веб-API находятся в файлах lib.deno.shared_globals.d.ts и lib.deno.window.d.ts.
Определения, относящиеся к воркерам, находятся в файле lib.deno.worker.d.ts.
Location
Deno поддерживает глобальный объект location из веб-платформы.
Флаг location
В процессе Deno нет «веб-страницы», URL-адрес которой можно было бы использовать в качестве location. Вместо этого пользователи могут имитировать адрес документа, указав его в CLI с помощью флага --location. Это может быть URL-адрес http или https.
// deno run --location https://example.com/path main.ts
console.log(location.href);
// "https://example.com/path"
Для этого необходимо передать --location <href>. Если этого не сделать, любая попытка обратиться к глобальному объекту location приведёт к ошибке.
// deno run main.ts
console.log(location.href);
// error: Uncaught ReferenceError: Access to "location", run again with --location <href>.
Изменение location или любого из его полей обычно вызывает навигацию в браузерах. В Deno это неприменимо, поэтому в такой ситуации будет выброшена ошибка.
// deno run --location https://example.com/path main.ts
location.pathname = "./foo";
// error: Uncaught NotSupportedError: Cannot set "location.pathname".
Расширенное использование
В вебе при разрешении ресурсов (за исключением модулей) в качестве основы для относительных URL-адресов обычно используется значение location.href. Это влияет на некоторые веб-API, используемые в Deno.
Fetch API
// deno run --location https://api.github.com/ --allow-net main.ts
const response = await fetch("./orgs/denoland");
// Fetches "https://api.github.com/orgs/denoland".
Вызов fetch() выше вызвал бы ошибку, если бы не был передан флаг --location, поскольку в Deno нет аналога веб-адреса, который можно было бы использовать в качестве основы.
Модули воркеров
// deno run --location https://example.com/index.html --allow-net main.ts
const worker = new Worker("./workers/hello.ts", { type: "module" });
// Fetches worker module at "https://example.com/workers/hello.ts".
В приведённых выше случаях предпочтительно передавать URL-адреса полностью, а не полагаться на --location. При необходимости можно вручную задать базовый адрес относительного URL с помощью конструктора URL.
Флаг --location предназначен для тех, кому нужно имитировать адрес документа для конкретной цели и кто понимает, что это будет работать только на уровне приложения. Однако его также можно использовать, чтобы подавить ошибки, вызванные нецелесообразным обращением зависимости к глобальному объекту location.
Веб-хранилище
Web Storage API предоставляет API для хранения строковых ключей и значений. Сохранение данных работает аналогично браузеру; ограничение хранилища составляет 10 МБ. Глобальный объект sessionStorage сохраняет данные только для текущего контекста выполнения, тогда как localStorage сохраняет их между запусками.
В браузере localStorage сохраняет данные отдельно для каждого источника (фактически, для комбинации протокола, имени хоста и порта). Начиная с Deno 1.16, Deno использует набор правил для определения уникального расположения хранилища:
- При использовании флага
--locationдля уникального хранения данных используется источник location. Это значит, что locationhttp://example.com/a.ts,http://example.com/b.tsиhttp://example.com:80/будут использовать одно и то же хранилище, аhttps://example.com/— другое. - Если location не указан, но задан конфигурационный файл
--config, используется абсолютный путь к этому файлу. Это значит, чтоdeno run --config deno.jsonc a.tsиdeno run --config deno.jsonc b.tsбудут использовать одно и то же хранилище, аdeno run --config tsconfig.json a.ts— другое. - Если не заданы ни конфигурация, ни location, Deno использует абсолютный путь к главному модулю, чтобы определить, какие данные хранилища являются общими. Deno REPL генерирует «синтетический» главный модуль на основе текущего рабочего каталога, из которого запущен
deno. Это значит, что несколько запусков REPL из одного каталога будут использовать одни и те же сохранённые данныеlocalStorage.
Для установки, получения и удаления элементов из localStorage можно использовать следующий код:
// Set an item in localStorage
localStorage.setItem("myDemo", "Deno App");
// Read an item from localStorage
const cat = localStorage.getItem("myDemo");
// Remove an item from localStorage
localStorage.removeItem("myDemo");
// Remove all items from localStorage
localStorage.clear();
Веб-воркеры
Deno поддерживает Web Worker API.
Воркеры можно использовать для выполнения кода в нескольких потоках. Каждый экземпляр Worker выполняется в отдельном потоке, выделенном только для этого воркера.
В настоящее время Deno поддерживает только воркеры типа module, поэтому при создании нового воркера необходимо передавать параметр type: "module".
Использование относительных спецификаторов модулей в главном воркере поддерживается только при передаче --location <href> в CLI. Для переносимости это не рекомендуется. Вместо этого можно использовать конструктор URL и import.meta.url, чтобы легко создать спецификатор для расположенного рядом скрипта. Однако у выделенных воркеров location есть по умолчанию, поэтому им эта возможность доступна без дополнительных настроек.
// Good
new Worker(import.meta.resolve("./worker.js"), { type: "module" });
// Bad
new Worker(import.meta.resolve("./worker.js"));
new Worker(import.meta.resolve("./worker.js"), { type: "classic" });
new Worker("./worker.js", { type: "module" });
Как и в обычных модулях, в модулях воркеров можно использовать верхнеуровневый await. Однако обязательно зарегистрируйте обработчик сообщений до первого await, иначе сообщения могут быть потеряны. Это не ошибка Deno, а лишь неудачное взаимодействие функций; такое же поведение наблюдается во всех браузерах, поддерживающих воркеры-модули.
import { delay } from "jsr:@std/async@1/delay";
// First await: waits for a second, then continues running the module.
await delay(1000);
// The message handler is only set after that 1s delay, so some of the messages
// that reached the worker during that second might have been fired when no
// handler was registered.
self.onmessage = (evt) => {
console.log(evt.data);
};
Разрешения при создании экземпляра
Создание нового экземпляра Worker аналогично динамическому импорту, поэтому для этого действия Deno требует соответствующее разрешение.
Для воркеров, использующих локальные модули, требуется разрешение --allow-read:
new Worker(import.meta.resolve("./worker.ts"), { type: "module" });
console.log("hello world");
self.close();
$ deno run main.ts
error: Uncaught PermissionDenied: read access to "./worker.ts", run again with the --allow-read flag
$ deno run --allow-read main.ts
hello world
Для воркеров, использующих удалённые модули, требуется разрешение --allow-net:
new Worker("https://example.com/worker.ts", { type: "module" });
// This file is hosted at https://example.com/worker.ts
console.log("hello world");
self.close();
$ deno run main.ts
error: Uncaught PermissionDenied: net access to "https://example.com/worker.ts", run again with the --allow-net flag
$ deno run --allow-net main.ts
hello world
Использование Deno в воркере
const worker = new Worker(import.meta.resolve("./worker.js"), {
type: "module",
});
worker.postMessage({ filename: "./log.txt" });
self.onmessage = async (e) => {
const { filename } = e.data;
const text = await Deno.readTextFile(filename);
console.log(text);
self.close();
};
hello world
$ deno run --allow-read main.js
hello world
Настройка разрешений воркера
Это нестабильная функция Deno. Подробнее см. в разделе нестабильные функции.
Разрешения, доступные воркеру, аналогичны флагам разрешений CLI: любое разрешение, включённое в CLI, можно отключить на уровне Worker API. Подробное описание каждого параметра разрешений см. в документации по безопасности.
По умолчанию воркер наследует разрешения потока, в котором он был создан. Однако, чтобы пользователи могли ограничить доступ этого воркера, в Worker API предусмотрен параметр deno.permissions.
Для разрешений с гранулярным доступом можно передать список ресурсов, к которым воркеру будет разрешён доступ. Для разрешений, которые можно только включить или отключить, можно передать соответственно true или false:
const worker = new Worker(import.meta.resolve("./worker.js"), {
type: "module",
deno: {
permissions: {
net: [
"deno.land",
],
read: [
new URL("./file_1.txt", import.meta.url),
new URL("./file_2.txt", import.meta.url),
],
write: false,
},
},
});
В разрешения с гранулярным доступом можно передавать как абсолютные, так и относительные пути. Однако учитывайте, что относительные пути будут разрешаться относительно файла, в котором создаётся воркер, а не относительно расположения файла воркера:
const worker = new Worker(
new URL("./worker/worker.js", import.meta.url).href,
{
type: "module",
deno: {
permissions: {
read: [
"/home/user/Documents/deno/worker/file_1.txt",
"./worker/file_2.txt",
],
},
},
},
);
И deno.permissions, и его дочерние элементы поддерживают параметр "inherit", который означает, что воркер будет использовать разрешения родительского элемента:
// This worker will inherit its parent permissions
const worker = new Worker(import.meta.resolve("./worker.js"), {
type: "module",
deno: {
permissions: "inherit",
},
});
// This worker will inherit only the net permissions of its parent
const worker = new Worker(import.meta.resolve("./worker.js"), {
type: "module",
deno: {
permissions: {
env: false,
hrtime: false,
net: "inherit",
ffi: false,
read: false,
run: false,
write: false,
},
},
});
Если не указать параметр deno.permissions или один из его дочерних элементов, воркер по умолчанию унаследует разрешения:
// This worker will inherit its parent permissions
const worker = new Worker(import.meta.resolve("./worker.js"), {
type: "module",
});
// This worker will inherit all the permissions of its parent BUT net
const worker = new Worker(import.meta.resolve("./worker.js"), {
type: "module",
deno: {
permissions: {
net: false,
},
},
});
Чтобы полностью отключить разрешения воркера, передайте "none" параметру deno.permissions:
// This worker will not have any permissions enabled
const worker = new Worker(import.meta.resolve("./worker.js"), {
type: "module",
deno: {
permissions: "none",
},
});
Отклонения других API от спецификаций
Cache API
Реализованы только следующие API:
- CacheStorage::open()
- CacheStorage::has()
- CacheStorage::delete()
- Cache::match()
- Cache::put()
- Cache::delete()
Несколько отличий от браузеров:
- В API нельзя передавать относительные пути. Запрос может быть экземпляром Request или URL либо строкой URL.
-
match()иdelete()пока не поддерживают параметры запроса.
© 2018–2025 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/api/web/about