Cloudflare (BYOCDN)
此配置将代理流量(来自AI机器人和LLM用户代理的请求)路由到Edge优化后端服务(live.edgeoptimize.net)。 与往常一样,我们仍将从您的源头为人类访客和SEO机器人提供服务。 要测试配置,请在设置完成后查找响应中的标头x-edgeoptimize-request-id。
先决条件
在设置Cloudflare Worker路由规则之前,请确保您具有:
- 在您的域中启用了辅助进程的Cloudflare帐户。
- 访问Cloudflare中的域DNS设置。
- 已完成LLM Optimizer载入流程。
- 已完成到LLM Optimizer的CDN日志转发。
- 从Edge UI检索到LLM Optimizer优化API密钥。
检索API密钥的步骤:
-
导航到 客户配置 并选择 CDN配置 选项卡。
-
在 AI流量路由到部署优化 下,勾选 将优化部署到AI代理 复选框。
-
复制API密钥,并继续执行下面的路由配置步骤。
note note NOTE 在此阶段,状态可能显示红叉,指示设置尚未完成。 这是正常情况 — 一旦您完成下面的路由配置并且AI机器人流量开始流动,状态将更新为绿色复选标记,确认路由已成功启用。
此外,如果您需要上述步骤的任何帮助,请联系您的Adobe客户团队或llmo-at-edge@adobe.com。
路由的工作方式
正确配置后,Cloudflare Worker会截获来自代理用户代理的对您的域(例如www.example.com/page.html)的请求,并将其路由到Edge Optimize后端。 后端请求包含所需的标头。
正在测试后端请求
您可以通过直接向Edge优化后端发出请求来验证路由。
curl -svo /dev/null https://live.edgeoptimize.net/page.html \
-H 'x-forwarded-host: www.example.com' \
-H 'x-edgeoptimize-url: /page.html' \
-H 'x-edgeoptimize-api-key: $EDGE_OPTIMIZE_API_KEY' \
-H 'x-edgeoptimize-config: LLMCLIENT=TRUE;'
必需的标头
必须为对Edge优化后端的请求设置以下标头:
x-forwarded-hostwww.example.comx-edgeoptimize-url/page.html 或 /products?id=123x-edgeoptimize-api-keyyour-api-key-herex-edgeoptimize-configLLMCLIENT=TRUE;步骤1:创建Cloudflare工作进程
- 登录到Cloudflare功能板。
- 在侧栏中导航到工作程序和页面。
- 单击创建应用程序,然后单击创建辅助进程。
- 为您的工作人员命名(例如,
edge-optimize-router)。 - 单击 部署 以使用默认代码创建辅助进程。
步骤2:添加辅助进程代码
创建辅助进程后,单击 编辑代码 并将默认代码替换为以下内容:
/**
* Edge Optimize BYOCDN - Cloudflare Worker
*
* This worker routes requests from agentic bots (AI/LLM user agents) to the
* Edge Optimize backend service for optimized content delivery.
*
* Features:
* - Routes agentic bot traffic to Edge Optimize backend
* - Failover to origin on Edge Optimize errors (any 4XX or 5XX errors)
* - Loop protection to prevent infinite redirects
* - Human visitors and SEO bots are served from the origin as usual
*/
// List of agentic bot user agents to route to Edge Optimize
const AGENTIC_BOTS = [
'AdobeEdgeOptimize-AI',
'ChatGPT-User',
'GPTBot',
'OAI-SearchBot',
'PerplexityBot',
'Perplexity-User'
];
// Targeted paths for Edge Optimize routing
// Set to null to route all HTML pages, or specify an array of paths
const TARGETED_PATHS = null; // e.g., ['/', '/page.html', '/products']
// Failover configuration
// Failover on any 4XX client error or 5XX server error from Edge Optimize
const FAILOVER_ON_4XX = true; // Failover on any 4XX error (400-499)
const FAILOVER_ON_5XX = true; // Failover on any 5XX error (500-599)
export default {
async fetch(request, env, ctx) {
return await handleRequest(request, env, ctx);
},
};
async function handleRequest(request, env, ctx) {
const url = new URL(request.url);
const userAgent = request.headers.get("user-agent")?.toLowerCase() || "";
// Check if request is already processed (loop protection)
const isEdgeOptimizeRequest = !!request.headers.get("x-edgeoptimize-request");
// Construct the original path and query string
const pathAndQuery = `${url.pathname}${url.search}`;
// Check if the path matches HTML pages (no extension or .html extension)
const isHtmlPage = /(?:\/[^./]+|\.html|\/)$/.test(url.pathname);
// Check if path is in targeted paths (if specified)
const isTargetedPath = TARGETED_PATHS === null
? isHtmlPage
: (isHtmlPage && TARGETED_PATHS.includes(url.pathname));
// Check if user agent is an agentic bot
const isAgenticBot = AGENTIC_BOTS.some((ua) => userAgent.includes(ua.toLowerCase()));
// Route to Edge Optimize if:
// 1. Request is NOT already from Edge Optimize (prevents infinite loops)
// 2. User agent matches one of the agentic bots
// 3. Path is targeted for optimization
if (!isEdgeOptimizeRequest && isAgenticBot && isTargetedPath) {
// Build the Edge Optimize request URL
const edgeOptimizeURL = `https://live.edgeoptimize.net${pathAndQuery}`;
// Clone and modify headers for the Edge Optimize request
const edgeOptimizeHeaders = new Headers(request.headers);
// Remove any existing Edge Optimize headers for security
edgeOptimizeHeaders.delete("x-edgeoptimize-api-key");
edgeOptimizeHeaders.delete("x-edgeoptimize-url");
edgeOptimizeHeaders.delete("x-edgeoptimize-config");
// x-forwarded-host: The original site domain
// Use environment variable if set, otherwise use the request host
edgeOptimizeHeaders.set("x-forwarded-host", env.EDGE_OPTIMIZE_TARGET_HOST ?? url.host);
// x-edgeoptimize-api-key: Your Adobe-provided API key
edgeOptimizeHeaders.set("x-edgeoptimize-api-key", env.EDGE_OPTIMIZE_API_KEY);
// x-edgeoptimize-url: The original request URL path and query
edgeOptimizeHeaders.set("x-edgeoptimize-url", pathAndQuery);
// x-edgeoptimize-config: Configuration for cache key differentiation
edgeOptimizeHeaders.set("x-edgeoptimize-config", "LLMCLIENT=TRUE;");
try {
// Send request to Edge Optimize backend
const edgeOptimizeResponse = await fetch(new Request(edgeOptimizeURL, {
headers: edgeOptimizeHeaders,
redirect: "manual", // Preserve redirect responses from Edge Optimize
}), {
cf: {
cacheEverything: true, // Enable caching based on origin's cache-control headers
},
});
// Check if we need to failover to origin
const status = edgeOptimizeResponse.status;
const is4xxError = FAILOVER_ON_4XX && status >= 400 && status < 500;
const is5xxError = FAILOVER_ON_5XX && status >= 500 && status < 600;
if (is4xxError || is5xxError) {
console.log(`Edge Optimize returned ${status}, failing over to origin`);
return await failoverToOrigin(request, env, url);
}
// Return the Edge Optimize response
return edgeOptimizeResponse;
} catch (error) {
// Network error or timeout - failover to origin
console.log(`Edge Optimize request failed: ${error.message}, failing over to origin`);
return await failoverToOrigin(request, env, url);
}
}
// For all other requests (human users, SEO bots), pass through unchanged
return fetch(request);
}
/**
* Failover to origin server when Edge Optimize returns an error
* @param {Request} request - The original request
* @param {Object} env - Environment variables
* @param {URL} url - Parsed URL object
*/
async function failoverToOrigin(request, env, url) {
// Build origin URL
const originURL = `${url.protocol}//${env.EDGE_OPTIMIZE_TARGET_HOST}${url.pathname}${url.search}`;
// Prepare headers - clean Edge Optimize headers and add loop protection
const originHeaders = new Headers(request.headers);
originHeaders.set("Host", env.EDGE_OPTIMIZE_TARGET_HOST);
originHeaders.delete("x-edgeoptimize-api-key");
originHeaders.delete("x-edgeoptimize-url");
originHeaders.delete("x-edgeoptimize-config");
originHeaders.delete("x-forwarded-host");
originHeaders.set("x-edgeoptimize-request", "fo");
// Create and send origin request
const originRequest = new Request(originURL, {
method: request.method,
headers: originHeaders,
body: request.body,
redirect: "manual",
});
const originResponse = await fetch(originRequest);
// Add failover marker header to response
const modifiedResponse = new Response(originResponse.body, {
status: originResponse.status,
statusText: originResponse.statusText,
headers: originResponse.headers,
});
modifiedResponse.headers.set("x-edgeoptimize-fo", "1");
return modifiedResponse;
}
单击 保存并部署 以发布辅助进程。
步骤3:配置环境变量
环境变量安全地存储敏感配置,如您的API密钥。
-
在辅助进程的设置中,导航到设置 > 变量。
-
在 环境变量 下,单击添加变量。
-
添加以下变量:
table 0-row-3 1-row-3 2-row-3 变量名称 描述 必需 EDGE_OPTIMIZE_API_KEYAdobe提供的Edge优化API密钥。 是 EDGE_OPTIMIZE_TARGET_HOSTEdge优化请求的目标主机(作为 x-forwarded-host标头发送)和故障转移的原始域。 必须是没有协议的域(例如,www.example.com,而不是https://www.example.com)。是 -
对于API密钥,请单击 加密 以安全地存储它。
-
单击保存并部署。
步骤4:向域添加路由
要在您的域中激活工作程序,请执行以下操作:
- 转到工作人员的设置 > 触发器。
- 在 路由 下,单击添加路由。
- 输入您的域模式(例如,
www.example.com/*或example.com/*)。 - 从下拉列表中选择您的区域。
- 单击保存。
或者,您可以在区域级别配置路由:
- 在Cloudflare中导航到您的域。
- 转到工作人员路由。
- 单击 添加路由 并指定模式和辅助进程。
验证故障转移行为
如果Edge Optimize不可用或返回错误,工作人员将自动故障转移到您的来源。 故障转移响应包括x-edgeoptimize-fo标头:
< HTTP/2 200
< x-edgeoptimize-fo: 1
您可以在Cloudflare Worker日志中监视故障转移事件以解决问题。
了解辅助进程逻辑
Cloudflare Worker将实施以下逻辑:
-
用户代理检测:检查传入请求的用户代理是否与定义的任何代理机器人匹配(不区分大小写)。
-
路径定位:可以根据目标路径筛选请求。 默认情况下,所有HTML页面(以
/、无扩展名或.html结尾的URL)都会被路由。 您可以使用TARGETED_PATHS数组指定特定路径。 -
循环保护:
x-edgeoptimize-request标头阻止无限循环。 当Edge Optimize将请求发送回您的源时,此标头设置为"1",并且Worker传递请求时没有将其路由回Edge Optimize。 -
标头安全性:在设置Edge Optimize标头之前,工作进程将从传入请求中删除任何现有的
x-edgeoptimize-*标头,以防止标头注入攻击。 -
标头映射:辅助进程设置Edge优化所需的标头:
x-forwarded-host— 标识原始站点域。x-edgeoptimize-url— 保留原始请求路径和查询字符串。x-edgeoptimize-api-key— 通过Edge Optimize验证请求。x-edgeoptimize-config— 提供缓存键配置。
-
故障转移逻辑:如果Edge Optimize返回任何错误状态代码(4XX客户端错误或5XX服务器错误),或者请求由于网络错误而失败,则工作进程将使用
EDGE_OPTIMIZE_TARGET_HOST自动故障转移到您的源。 故障转移响应包含x-edgeoptimize-fo: 1标头以指示已发生故障转移。 -
重定向处理:
redirect: "manual"选项可确保将来自Edge Optimize的重定向响应传递到客户端,而无需辅助进程对其进行跟进。
自定义配置
您可以通过修改代码顶部的配置常量来自定义辅助进程行为:
代理机器人列表
修改AGENTIC_BOTS阵列以添加或删除用户代理:
const AGENTIC_BOTS = [
'AdobeEdgeOptimize-AI',
'ChatGPT-User',
'GPTBot',
'OAI-SearchBot',
'PerplexityBot',
'Perplexity-User',
// Add additional user agents as needed
'ClaudeBot',
'Anthropic-AI'
];
目标路径
默认情况下,所有HTML页面都会被路由到Edge Optimize。 要将路由限制到特定路径,请修改TARGETED_PATHS数组:
// Route all HTML pages (default)
const TARGETED_PATHS = null;
// Or specify exact paths to route
const TARGETED_PATHS = ['/', '/page.html', '/products', '/about-us'];
故障转移配置
默认情况下,如果出现Edge优化中的任何4XX或5XX错误,工作进程将进行故障切换。 自定义此行为:
// Default: failover on any 4XX or 5XX error
const FAILOVER_ON_4XX = true;
const FAILOVER_ON_5XX = true;
// Failover only on 5XX server errors (not 4XX client errors)
const FAILOVER_ON_4XX = false;
const FAILOVER_ON_5XX = true;
// Disable automatic failover (not recommended)
const FAILOVER_ON_4XX = false;
const FAILOVER_ON_5XX = false;
重要注意事项
-
故障转移行为:如果Edge Optimize返回任何错误(4XX或5XX状态代码),或者请求由于网络错误而失败,则工作进程会自动故障转移到您的源。 故障转移使用
EDGE_OPTIMIZE_TARGET_HOST作为原始域(类似于Fastly的F_Default_Origin或CloudFront的Default_Origin)。 故障转移响应包括x-edgeoptimize-fo: 1标头,可用于监视和调试。 -
缓存:默认情况下,Cloudflare将根据URL缓存响应。 由于代理流量接收的内容与人工流量不同,因此请确保您的缓存配置考虑到了这一点。 请考虑使用缓存API或缓存标头来区分缓存的内容。
x-edgeoptimize-config标头应包含在您的缓存键中。 -
速率限制:监视您的Edge优化使用情况,并在需要时考虑为代理流量实施速率限制。
-
测试:在部署到生产环境之前,始终在暂存环境中测试配置。 验证代理流量和人流量是否均可按预期运行。 通过模拟Edge优化错误来测试故障转移行为。
-
日志记录:启用Cloudflare Workers日志记录以监视请求并排除问题。 导航到工作程序 > 您的工作程序 > 日志以查看实时日志。 工作进程会记录故障转移事件以进行调试。
疑难解答
x-edgeoptimize-request-id标头AGENTIC_BOTS阵列中。EDGE_OPTIMIZE_API_KEY。 请联系Adobe以确认您的API密钥处于活动状态。x-edgeoptimize-request标头检查已准备就绪。TARGETED_PATHS是否正确配置。x-edgeoptimize-fo: 1标头FAILOVER_ON_4XX和FAILOVER_ON_5XX是否设置为true。 检查工作进程日志中的错误消息。TARGETED_PATHS (如果已指定)中并与HTML页面正则表达式模式匹配。EDGE_OPTIMIZE_TARGET_HOST包含协议(例如,https://)。example.com,而不是https://example.com)。验证设置
完成设置后,验证是否正在将机器人流量路由到Edge Optimize,以及人流量是否不受影响。
1. 测试机器人流量(应优化)
使用代理用户代理模拟AI机器人请求:
curl -svo /dev/null https://www.example.com/page.html \
--header "user-agent: chatgpt-user"
成功的响应包括x-edgeoptimize-request-id标头,用于确认请求是通过Edge优化路由的:
< HTTP/2 200
< x-edgeoptimize-request-id: 50fce12d-0519-4fc6-af78-d928785c1b85
2. 测试人员流量(不应受影响)
模拟常规的人类浏览器请求:
curl -svo /dev/null https://www.example.com/page.html \
--header "user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
响应应 不 包含x-edgeoptimize-request-id标头。 在Edge中启用优化之前,页面内容和响应时间应保持相同。
3. 如何区分这两种方案
x-edgeoptimize-request-idx-edgeoptimize-fo1)也可以在LLM Optimizer UI中查看流量路由的状态。 导航到 客户配置 并选择 CDN配置 选项卡。
要进一步了解Edge优化,包括可用的机会、自动优化工作流和常见问题,请返回Edge优化概述。