跳转到内容
搜索文档

使用 Workers 管理托管图像

最后更新 查看 MarkdownAgent 设置

绑定(binding) 将您的 Worker 连接到 Developer Platform 上的外部资源,如 ImagesR2 存储桶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 对象中的以下选项:

  • id string — 分配给图像的自定义 ID。如果省略,Cloudflare 生成 UUID。请参阅上传到自定义路径
  • filename string — 与图像关联的文件名。
  • requireSignedURLs boolean — 设置查看图像是否需要签名 URL。默认为 false
  • metadata Record<string, unknown> — 与图像一起存储的任意元数据。
  • creator string — 图像创建者的用户定义标识符。
  • encoding 'base64' — 如果提供的字节是 base64 编码的,设置为 base64。绑定将在上传前解码它们。

.list(options)

分页列出账户中的图像。返回 ImageList

接受 ImageListOptions 对象中的以下选项:

  • limit number — 页面中返回的最大图像数。
  • cursor string — 上一次 list() 调用返回的延续令牌。第一页省略。
  • sortOrder 'asc' | 'desc' — 按 uploaded 时间戳排序结果的顺序。默认为 asc
  • creator string — 将结果过滤为使用此创建者标识符上传的图像。

.image(imageId)

返回单个托管图像的句柄。imageId 可以是 Cloudflare 生成的 UUID 或自定义 ID

句柄本身不进行网络请求,因此构造成本很低。

.image(imageId).details()

获取图像的元数据。返回 ImageMetadatanull(如果不存在给定 ID 的图像)。

.image(imageId).bytes()

获取图像的原始字节。返回 ReadableStream<Uint8Array>null(如果不存在给定 ID 的图像)。这流式传输原始上传的文件。将图像字节传递给 .input() 以在提供前优化,或使用 ImageMetadata.variants图像交付 URL 中返回的 URL 提供预定义变体。

.image(imageId).update(options)

更新图像的元数据或访问控制。所有字段都是可选的;仅更改指定的字段。返回带有更新值的 ImageMetadata

接受 ImageUpdateOptions 对象中的以下选项:

  • requireSignedURLs boolean — 查看图像是否需要签名 URL。无法在使用自定义 ID 上传的图像上设置为 true
  • metadata Record<string, unknown> — 图像的替换元数据。这将替换现有元数据而不是合并。
  • creator string — 图像创建者的用户定义标识符。

.image(imageId).delete()

删除图像。如果图像已删除返回 true,如果不存在给定 ID 的图像返回 false

示例

从请求体上传图像

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",绑定将在上传前为您解码 body。

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

检索、创建或更新图像的操作返回。

  • id string
    • 图像的唯一标识符。
  • filename stringoptional
    • 上传时提供的原始文件名。
  • uploaded stringoptional
    • 图像上传的日期和时间,ISO 8601 字符串。
  • requireSignedURLs boolean
  • meta Record<string, unknown>optional
    • 与图像关联的用户提供的元数据。
  • variants Array<string>
    • 账户上配置的每个变体的完整 URL。请参阅创建变体
  • draft booleanoptional
    • 图像是否处于草稿状态(尚未上传字节)。草稿通常仅在账户使用 Direct Creator Uploads 时可见。
  • creator stringoptional
    • 图像创建者的用户定义标识符。

ImageList

list() 返回。

  • images Array<ImageMetadata>
    • 此页结果中的图像。
  • cursor stringoptional
    • 传递给下一次 list() 调用的延续令牌。仅在有更多结果时存在。
  • listComplete boolean
    • 没有更多页面时为 true,否则为 false

错误处理

失败的方法抛出 ImagesError.upload().list().update() — 具有以下属性:

  • code number
    • 标识失败模式的数字错误代码。
  • message string
    • 错误的人类可读描述。

获取单张图像的方法 — .details().bytes().delete() — 对于"未找到"返回 nullfalse 而不是抛出。

您可能希望将可能抛出的操作包装在 try...catch 块中。

本地开发

运行 wrangler dev 时,管理托管图像的操作由本地 mock 提供,将图像存储在嵌入式 KV 命名空间中。mock 支持本页记录的每个方法,因此您可以离线开发和测试 Worker。

mock 仅适用于本地开发。要从本地环境使用真实的 Images 服务,请运行 wrangler dev --remote

相关资源

这篇文档对您有帮助吗?