INTEGRITY Документация

Управление хостируемыми изображениями с помощью 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 объект:

.list(options)

Выводит список изображений в вашем аккаунте с пагинацией. Возвращает ImageList.

Принимает следующие параметры в виде ImageListOptions объект:

.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 объект:

.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

Возвращается операциями получения, создания или обновления изображения.

ImageList

Возвращается list().

Обработка ошибок

Методы, которые завершаются ошибкой, выбрасывают ImagesError, .upload(), .list(), .update(), со следующими свойствами:

Методы, которые получают одно изображение: .details(), .bytes(), а также .delete(), возвращают null или false для случая «не найдено» вместо выброса исключения.

Операции, которые могут завершиться исключением, бывает удобно обернуть в try...catch блок.

Локальная разработка

Когда вы выполняете wrangler dev, операции управления размещёнными изображениями выполняет локальный мок, который хранит изображения во встроенном пространстве имён KV. Мок поддерживает все методы, описанные на этой странице, поэтому вы можете разрабатывать и тестировать Worker в автономном режиме.

Мок-объект подходит только для локальной разработки. Чтобы обратиться к реальному сервису Images из локального окружения, выполните wrangler dev --remote.