← Images / images / storage
Управление хостируемыми изображениями с помощью Workers
A привязка подключает ваш Worker на внешние ресурсы на Developer Platform, например Изображения, Бакеты R2, или Пространства имён KV.
При работе с размещёнными изображениями привязка Images позволяет Worker загружать, получать список, запрашивать, обновлять и удалять изображения без прямых обращений к REST API. Привязка hosted предоставляет операции хранения и управления. Эту привязку также можно использовать, чтобы оптимизация размещённых изображений.
Привязки можно настроить в панели управления Cloudflare для вашего Worker или в конфигурационном файле Wrangler в каталоге проекта.
Настройка
Чтобы привязать Images к вашему Worker, добавьте следующее в файл конфигурации Wrangler:
{
"images": {
"binding": "IMAGES", // available in your Worker on env.IMAGES
},
}[images]
binding = "IMAGES"В коде своего Worker вы можете управлять размещёнными изображениями с помощью env.IMAGES.hosted пространство имён.
Методы
env.IMAGES.hosted позволяет загружать изображения и получать их список в рамках аккаунта. Для управления конкретным изображением вызовите .image(imageId) чтобы получить дескриптор, а затем вызвать на нём метод.
.upload(image, options)
Загружает новое изображение в ваш аккаунт. Байты изображения можно передать в виде потока или ArrayBuffer. Возвращает ImageMetadata.
Принимает следующие параметры в виде ImageUploadOptions объект:
idstring, пользовательский ID для присвоения изображению. Если не указан, Cloudflare создаёт UUID. См. Загрузка по пользовательскому пути.filenamestring, имя файла, связываемое с изображением.requireSignedURLsboolean, задаёт, требуется ли для просмотра изображения подписанный URL. По умолчаниюfalse.metadataRecord<string, unknown>, произвольные метаданные для хранения вместе с изображением.creatorstring, определяемый пользователем идентификатор автора изображения.encoding'base64': установите вbase64если переданные байты закодированы в base64. Привязка декодирует их перед загрузкой.
.list(options)
Выводит список изображений в вашем аккаунте с пагинацией. Возвращает ImageList.
Принимает следующие параметры в виде ImageListOptions объект:
limitnumber, максимальное количество изображений, возвращаемых на странице.cursorstring, токен продолжения, возвращённый предыдущимlist()вызов. Не указывайте на первой странице.sortOrder'asc' | 'desc', порядок сортировки результатов поuploadedвременную метку. По умолчанию:asc.creatorstring, отфильтруйте результаты по изображениям, загруженным с этим идентификатором автора.
.image(imageId)
Возвращает дескриптор одного размещённого изображения. Свойство imageId может быть UUID, сгенерированным Cloudflare, или custom ID.
Сам по себе хендл не выполняет сетевой запрос, поэтому его создание практически ничего не стоит.
.image(imageId).details()
Получает метаданные изображения. Возвращает ImageMetadata или null если изображение с указанным ID не существует.
.image(imageId).bytes()
Получает необработанные байты изображения. Возвращает ReadableStream<Uint8Array> или null если изображение с указанным ID не существует. При этом исходный загруженный файл передаётся потоком. Передайте байты изображения в .input() для оптимизации перед отдачей, либо использовать URL, возвращённые в ImageMetadata.variants или URL доставки изображения чтобы отдавать предопределённый вариант.
.image(imageId).update(options)
Обновляет метаданные или элементы управления доступом для изображения. Все поля необязательны: будут изменены только указанные. Возвращает ImageMetadata с обновлёнными значениями.
Принимает следующие параметры в виде ImageUpdateOptions объект:
requireSignedURLsboolean, требуются ли подписанные URL для просмотра изображения. Нельзя задать значениеtrueдля изображения, загруженного с custom ID.metadataRecord<string, unknown>, метаданные для замены. Они заменяют существующие метаданные, а не объединяются с ними.creatorstring, определяемый пользователем идентификатор автора изображения.
.image(imageId).delete()
Удаляет изображение. Возвращает true если изображение было удалено или false если изображение с указанным ID не существовало.
Примеры
Загрузка изображения из тела запроса
export default {
async fetch(request, env) {
if (!request.body) {
return new Response("Missing body", { status: 400 });
}
const image = await env.IMAGES.hosted.upload(request.body, {
filename: "upload.jpg",
metadata: { source: "worker" },
requireSignedURLs: false,
});
return Response.json(image);
},
};export default {
async fetch(request, env) {
if (!request.body) {
return new Response("Missing body", { status: 400 });
}
const image = await env.IMAGES.hosted.upload(request.body, {
filename: "upload.jpg",
metadata: { source: "worker" },
requireSignedURLs: false,
});
return Response.json(image);
},
};Загрузка изображения в кодировке base64
Задайте encoding: "base64" и привязка декодирует тело за вас перед загрузкой.
export default {
async fetch(request, env) {
if (!request.body) {
return new Response("Missing body", { status: 400 });
}
const image = await env.IMAGES.hosted.upload(request.body, {
encoding: "base64",
filename: "upload.png",
});
return Response.json(image);
},
};export default {
async fetch(request, env) {
if (!request.body) {
return new Response("Missing body", { status: 400 });
}
const image = await env.IMAGES.hosted.upload(request.body, {
encoding: "base64",
filename: "upload.png",
});
return Response.json(image);
},
};Список изображений с пагинацией
export default {
async fetch(request, env) {
let cursor;
const ids = [];
do {
const page = await env.IMAGES.hosted.list({ limit: 100, cursor });
ids.push(...page.images.map((image) => image.id));
cursor = page.cursor;
} while (cursor);
return Response.json({ count: ids.length, ids });
},
};export default {
async fetch(request, env) {
let cursor: string | undefined;
const ids: string[] = [];
do {
const page = await env.IMAGES.hosted.list({ limit: 100, cursor });
ids.push(...page.images.map((image) => image.id));
cursor = page.cursor;
} while (cursor);
return Response.json({ count: ids.length, ids });
},
};Получение сведений об одном изображении
export default {
async fetch(request, env) {
const details = await env.IMAGES.hosted.image("IMAGE_ID").details();
if (!details) {
return new Response("Not found", { status: 404 });
}
return Response.json(details);
},
};export default {
async fetch(request, env) {
const details = await env.IMAGES.hosted.image("IMAGE_ID").details();
if (!details) {
return new Response("Not found", { status: 404 });
}
return Response.json(details);
},
};Транслировать исходные байты изображения
export default {
async fetch(request, env) {
const bytes = await env.IMAGES.hosted.image("IMAGE_ID").bytes();
if (!bytes) {
return new Response("Not found", { status: 404 });
}
return new Response(bytes);
},
};export default {
async fetch(request, env) {
const bytes = await env.IMAGES.hosted.image("IMAGE_ID").bytes();
if (!bytes) {
return new Response("Not found", { status: 404 });
}
return new Response(bytes);
},
};Обновить метаданные изображения
export default {
async fetch(request, env) {
const updated = await env.IMAGES.hosted.image("IMAGE_ID").update({
metadata: { reviewed: true },
});
return Response.json(updated);
},
};export default {
async fetch(request, env) {
const updated = await env.IMAGES.hosted.image("IMAGE_ID").update({
metadata: { reviewed: true },
});
return Response.json(updated);
},
};Удаление изображения
export default {
async fetch(request, env) {
const deleted = await env.IMAGES.hosted.image("IMAGE_ID").delete();
return new Response(deleted ? "Deleted" : "Not found", {
status: deleted ? 200 : 404,
});
},
};export default {
async fetch(request, env) {
const deleted = await env.IMAGES.hosted.image("IMAGE_ID").delete();
return new Response(deleted ? "Deleted" : "Not found", {
status: deleted ? 200 : 404,
});
},
};Загрузка удалённого изображения в хранилище Images
В этом примере изображение загружается с удаленного URL-адреса, отправляется в ваш аккаунт Images, после чего возвращается URL-адрес первого варианта.
export default {
async fetch(request, env) {
const upstream = await fetch("https://example.com/photo.jpg");
if (!upstream.ok || !upstream.body) {
return new Response("Upstream fetch failed", { status: 502 });
}
const image = await env.IMAGES.hosted.upload(upstream.body, {
filename: "photo.jpg",
metadata: { source: "example.com" },
});
return Response.json({
id: image.id,
variant: image.variants[0],
});
},
};export default {
async fetch(request, env) {
const upstream = await fetch("https://example.com/photo.jpg");
if (!upstream.ok || !upstream.body) {
return new Response("Upstream fetch failed", { status: 502 });
}
const image = await env.IMAGES.hosted.upload(upstream.body, {
filename: "photo.jpg",
metadata: { source: "example.com" },
});
return Response.json({
id: image.id,
variant: image.variants[0],
});
},
};Определения типов
ImageMetadata
Возвращается операциями получения, создания или обновления изображения.
idstring- Уникальный идентификатор изображения.
filenamestringнеобязательно- Исходное имя файла, указанное при загрузке.
uploadedstringнеобязательно- Дата и время загрузки изображения в виде строки формата ISO 8601.
requireSignedURLsboolean- Требуются ли подписанные URL для доступа к этому изображению. См. Обслуживание приватных изображений.
metaRecord<string, unknown>необязательно- Метаданные, указанные пользователем и связанные с изображением.
variantsArray<string>- Полностью готовые URL для каждого варианта, настроенного в вашей учётной записи. См. Создание вариантов.
draftbooleanнеобязательно- Находится ли изображение в состоянии черновика (байты ещё не загружены). Черновики обычно встречаются только на аккаунтах, использующих Direct Creator Uploads.
creatorstringнеобязательно- Определяемый пользователем идентификатор автора изображения.
ImageList
Возвращается list().
imagesArray<ImageMetadata>- Изображения на этой странице результатов.
cursorstringнеобязательно- Токен продолжения, который передаётся в следующий
list()вызов. Присутствует, только если есть дополнительные результаты.
- Токен продолжения, который передаётся в следующий
listCompletebooleantrueкогда больше нет страниц,falseв противном случае.
Обработка ошибок
Методы, которые завершаются ошибкой, выбрасывают ImagesError, .upload(), .list(), .update(), со следующими свойствами:
codenumber- Числовой код ошибки, определяющий тип сбоя.
messagestring- Понятное человеку описание ошибки.
Методы, которые получают одно изображение: .details(), .bytes(), а также .delete(), возвращают null или false для случая «не найдено» вместо выброса исключения.
Операции, которые могут завершиться исключением, бывает удобно обернуть в try...catch блок.
Локальная разработка
Когда вы выполняете wrangler dev, операции управления размещёнными изображениями выполняет локальный мок, который хранит изображения во встроенном пространстве имён KV. Мок поддерживает все методы, описанные на этой странице, поэтому вы можете разрабатывать и тестировать Worker в автономном режиме.
Мок-объект подходит только для локальной разработки. Чтобы обратиться к реальному сервису Images из локального окружения, выполните wrangler dev --remote.
Дополнительные материалы
- Оптимизация с помощью Workers, используйте привязку для оптимизации изображений из Worker.
- Загрузка через REST API, эквивалентный HTTP API.
- Управление хостируемыми изображениями, работа с сохранёнными изображениями через дашборд и API.