跳转到内容
本站为社区维护的非官方中文翻译,与 Cloudflare, Inc. 无关联。本站不提供账户登录,请勿在任何非官方站点输入您的 Cloudflare 账户信息。官方文档:developers.cloudflare.com

Guardrails

最后更新 查看 MarkdownAgent 设置

Guardrails 将 Browser Run 会话的 HTTP 和 HTTPS 请求限制为允许的主机名。

这使你可以:

  • 保持自动化聚焦 — 将每个会话限制为其任务所需的主机名。
  • 支持页面依赖 — 包含所需的第三方 API、脚本、图片和字体。
  • 运行自包含页面 — 阻止外部 HTTP 和 HTTPS 请求。

会话 Guardrails 适用于使用 Puppeteer、Playwright 或 Chrome DevTools Protocol (CDP) 创建的浏览器会话。它们不适用于 Quick Actions。

设置 Guardrails

添加浏览器将访问的主机名,以及重定向、API、脚本、图片或字体所需的任何主机名。对于常见或共享的主机名,使用 domain set,而不是逐个列出每个主机名。

在启动新会话时设置 Guardrails。该策略在该会话的生命周期内保持固定。

根据你维护允许列表的方式选择属性:

属性 类型 适用场景 限制
allowedDomains string[] 工作流需要简短、稳定且精确控制主机名的列表。 50 个条目
allowedDomainSets string[] 多个会话共享较长列表,或由团队集中维护一份列表。 4 个条目

两个属性均为可选,并组成一份允许列表。如果两者都省略,HTTP 和 HTTPS 请求不受限制。

检查策略要求

启动会话前,请确保 Guardrail 策略满足以下要求:

  • allowedDomains 中最多添加 50 个条目。
  • allowedDomainSets 中最多添加 4 个条目。
  • 编写主机名模式时不要包含 scheme、端口或路径。
  • 每个主机名模式最多使用一个通配符。

如果策略不满足这些要求,Browser Run 会以 400 响应拒绝会话请求。

使用 Puppeteer 启动受保护的会话

此函数启动一个允许 example.com、其子域以及 common-cdns domain set 中主机名的会话。

该示例假定浏览器绑定名为 MYBROWSER。

src/index.jsjs
import puppeteer from "@cloudflare/puppeteer";

export async function startGuardedSession(env) {
	const browser = await puppeteer.launch(env.MYBROWSER, {
		guardrails: {
			allowedDomains: ["example.com", "*.example.com"],
			allowedDomainSets: ["common-cdns"],
		},
	});

	return browser;
}
src/index.tsts
import puppeteer from "@cloudflare/puppeteer";

interface Env {
	MYBROWSER: Fetcher;
}

export async function startGuardedSession(env: Env) {
	const browser = await puppeteer.launch(env.MYBROWSER, {
		guardrails: {
			allowedDomains: ["example.com", "*.example.com"],
			allowedDomainSets: ["common-cdns"],
		},
	});

	return browser;
}

Playwright 通过其 launch() 选项接受相同的 guardrails 对象。

REST API

使用 REST API 在 Workers 之外获取受保护的会话。此请求假定已设置 $ACCOUNT_ID,且 $CLOUDFLARE_API_TOKEN 具有 Browser Rendering Write 权限。

curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/browser-run/devtools/browser" \
	--request POST \
	--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
	--json '{
		"guardrails": {
				"allowedDomains": [
						"example.com",
						"*.example.com"
				],
				"allowedDomainSets": [
						"common-cdns"
				]
		}
	}'

添加允许的主机名

使用 allowedDomains 指定浏览器可以请求的主机名。

每个条目只能包含主机名。不要包含 https:// 等协议、:443 等端口或 /api 等路径。

  • example.com 仅允许 example.com。
  • *.example.com 允许 www.example.com 和 api.example.com 等子域,但不允许 example.com。

你可以在每个条目中使用一个 * 通配符来匹配主机名的变体:

模式 匹配 不匹配
example.com example.com www.example.com、evil-example.com
*.example.com www.example.com、api.v1.example.com example.com、evilexample.com
*example.com example.com、www.example.com、evilexample.com example.net
api.*.example.com api.v1.example.com、api.staging.example.com api.example.com

使用 domain set

Domain set 帮助你在会话之间复用共享的主机名列表。allowedDomainSets 属性接受 common-cdns 集名称和 HTTPS URL。

允许常见 CDN 主机名

当你的页面依赖常见内容分发网络(CDN)主机名提供的资源时,使用 Cloudflare 维护的 common-cdns 集:

{
	"allowedDomains": ["example.com"],
	"allowedDomainSets": ["common-cdns"]
}

Cloudflare 维护 common-cdns 集,并可能随时间更改。当你需要固定的允许主机名集合时,使用 allowedDomains 或托管的主机名列表。

使用托管的主机名列表

对特定于你的页面和依赖项的主机名模式,使用 HTTPS URL:

{
	"allowedDomainSets": ["https://example.com/browser-run-hostnames.txt"]
}

例如,browser-run-hostnames.txt 可以包含:

example.com
*.example.com

# Third-party API
api.example.net

托管列表必须满足以下要求:

要求 值
协议 HTTPS
内容类型 text/plain
行格式 每行一个主机名模式
注释 以 # 开头的行和空行会被忽略
验证 一行无效会拒绝整个托管列表

Cloudflare 最多将托管列表缓存一小时。缓存刷新后的更新仅影响新启动的会话,不影响现有会话。

阻止所有 Web 请求

空的 allowedDomains 数组会阻止所有 HTTP 和 HTTPS 请求。适用于自包含页面,例如将内联 HTML 渲染为屏幕截图或 PDF。

内联内容可以渲染,但浏览器无法请求外部 API 或资源。此策略不要包含任何 domain set。

在受支持的集成中,将此策略对象用作 guardrails 的值:

{
	"allowedDomains": []
}

验证被阻止的请求

使用 Puppeteer 请求允许列表之外的主机名。此示例检查响应状态和 Guardrail 请求头。

import puppeteer from "@cloudflare/puppeteer";

export async function verifyGuardrails(env) {
	const browser = await puppeteer.launch(env.MYBROWSER, {
		guardrails: {
			allowedDomains: ["example.com"],
		},
	});

	try {
		const page = await browser.newPage();
		const response = await page.goto("https://example.org");
		const status = response?.status();
		const headers = response?.headers() ?? {};

		if (
			status !== 403 ||
			headers["cf-mitigated"] !== "guardrails" ||
			headers["cf-brapi-guardrails-reason"] !== "not-in-allowlist"
		) {
			throw new Error("Expected Browser Run guardrails to block the request");
		}
	} finally {
		await browser.close();
	}
}
import puppeteer from "@cloudflare/puppeteer";

interface Env {
	MYBROWSER: Fetcher;
}

export async function verifyGuardrails(env: Env) {
	const browser = await puppeteer.launch(env.MYBROWSER, {
		guardrails: {
			allowedDomains: ["example.com"],
		},
	});

	try {
		const page = await browser.newPage();
		const response = await page.goto("https://example.org");
		const status = response?.status();
		const headers = response?.headers() ?? {};

		if (
			status !== 403 ||
			headers["cf-mitigated"] !== "guardrails" ||
			headers["cf-brapi-guardrails-reason"] !== "not-in-allowlist"
		) {
			throw new Error("Expected Browser Run guardrails to block the request");
		}
	} finally {
		await browser.close();
	}
}

被阻止的请求返回带有以下请求头的 403 响应:

请求头 值 含义
cf-mitigated guardrails 确认 Guardrails 阻止了该请求
cf-brapi-guardrails-reason not-in-allowlist 请求的主机名未被允许

将 Guardrails 与 Live View 一起使用

使用 Live View 时,会话 Guardrails 仍然生效。{ mode: "readonly" } Live View 设置控制查看者交互,不会更改会话的主机名允许列表。

这篇文档对您有帮助吗?