跳转到内容
搜索文档

自定义元数据

最后更新 查看 MarkdownAgent 设置

你可能希望配置超出 Rules 或 Rate Limiting 规模的按主机名(客户)设置。

为此,你首先需要联系账户团队以启用对 Custom Metadata 的访问。配置自定义元数据后,可以通过以下方式使用:

  • Cloudflare Workers 读取元数据 JSON(需要访问 Workers)以定义按主机名的行为。
  • 在不同 Cloudflare 安全产品的规则表达式中使用自定义元数据值来定义规则范围。

示例

  • 按客户的 URL 重写 — 例如,客户 1–10,000 从服务器 A 获取资源,10,001–20,000 从服务器 B 获取,等等。
  • 添加自定义标头 — 例如,根据你提供的元数据添加 X-Customer-ID: $number
  • 按客户设置 HTTP Strict Transport Security(“HSTS”)标头

请与你的 Solutions Engineer 讨论其他逻辑和要求。

提交自定义元数据

你可以通过 Custom Hostnames API 向 Cloudflare 添加自定义元数据。可以通过向特定主机名 ID 发送 PATCH 请求 来添加此数据,从而为该主机名设置元数据,例如:

Required API token permissions

At least one of the following token permissions is required:
  • SSL and Certificates Write
Edit Custom Hostnamebash
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames/$CUSTOM_HOSTNAME_ID" \
	--request PATCH \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
	--json '{
		"ssl": {
				"method": "http",
				"type": "dv"
		},
		"custom_metadata": {
				"customer_id": "12345",
				"redirect_to_https": true,
				"security_tag": "low"
		}
	}'

元数据的更改将在 30 秒内传播到 Cloudflare 的边缘。


从 Cloudflare Worker 访问自定义元数据

元数据对象可通过每个请求上的 request.cf.hostMetadata 属性访问。然后你可以读取数据,并使用 Worker 基于该数据自定义任何行为。

在以下示例中,我们将在 Worker 中使用通过上方 API 调用提交的 user_id:"custom_metadata":{"customer_id":"12345","redirect_to_https": true,"security_tag":"low"},并设置一个请求标头以将 customer_id 发送到源站:

export default {
	/**
	 * Fetch and add a X-Customer-Id header to the origin based on hostname
	 * @param {Request} request
	 */
	async fetch(request, env, ctx) {
		const customer_id = request.cf.hostMetadata.customer_id;
		const newHeaders = new Headers(request.headers);
		newHeaders.append("X-Customer-Id", customer_id);

		const init = {
			headers: newHeaders,
			method: request.method,
		};
		return fetch(request.url, init);
	},
};
export default {
	/**
	 * Fetch and add a X-Customer-Id header to the origin based on hostname
	 * @param {Request} request
	 */
	async fetch(request, env, ctx): Promise<Response> {
		const customer_id = request.cf.hostMetadata.customer_id;
		const newHeaders = new Headers(request.headers);
		newHeaders.append("X-Customer-Id", customer_id);

		const init = {
			headers: newHeaders,
			method: request.method,
		};
		return fetch(request.url, init);
	},
} satisfies ExportedHandler<Env>;

在规则表达式中访问自定义元数据

使用 cf.hostname.metadata 字段在规则表达式中访问元数据对象。要从 JSON 对象获取不同的值,请使用 lookup_json_string 函数。

以下规则表达式定义:如果自定义元数据中的 security_tag 值包含 low,则规则匹配:

lookup_json_string(cf.hostname.metadata, "security_tag") eq "low"

最佳实践

  • 确保所用 JSON schema 固定:在没有相应 Cloudflare Workers 更改的情况下更改 schema,可能会导致网站中断,或回退到任何已定义的“默认”行为
  • 优先使用扁平 JSON 结构
  • 使用 snake_case 的字符串键(而不是 camelCase 或 PascalCase)
  • 使用正确的布尔值(true/false,而不是 true10
  • 使用数字表示整数,而不是字符串(使用 12,而不是 "1""2"
  • 在没有元数据时定义回退行为
  • 在元数据中的键或值未知时定义回退行为

一般指导是在适当情况下遵循 Google 的 JSON Style guide


限制

向 Cloudflare 提供的元数据存在一些限制:

  • 必须是有效的 JSON。
  • 任何源站解析 — 例如,将给定主机名的请求定向到特定后端 — 都必须作为 Cloudflare DNS 中存在的主机名提供(即使是非权威设置)。直接提供 IP 地址会导致请求出错。
  • 总负载不得超过 4 KB。
  • 需要一个知道如何处理 schema 并根据内容触发逻辑的 Cloudflare Worker。

Terraform 支持

Terraform 仅允许单一类型的 map,因此 Cloudflare 对自定义主机名自定义元数据的 Terraform 支持仅限于字符串键和值。

这篇文档对您有帮助吗?