跳转到内容
搜索文档

使用 Workers 管理托管图像

最后更新 查看 MarkdownAgent 设置

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

  • 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()

获取图像的元数据。返回 ImageMetadata 或 null(如果不存在给定 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() — 对于"未找到"返回 null 或 false 而不是抛出。

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

本地开发

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

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

相关资源

这篇文档对您有帮助吗?