You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Cloudflare Workers根据请求IP动态设置源站的问题咨询

如何在Cloudflare Worker中根据请求IP动态切换源站?

我来帮你搞定这个问题!你当前的代码已经能识别内部IP的请求,但还没真正修改请求的目标源站——这就是为什么请求还是会打到原来的站点。要实现动态切换源,核心是创建一个新的Request对象,并指定你想要的目标源地址,Cloudflare Worker提供了两种常用的方式:

方法一:使用Cloudflare专属的cf.resolveOverride(推荐)

这种方式是Cloudflare专门为源站切换设计的,不需要修改整个请求URL,直接指定要解析的源站主机名即可,非常适合同域名下切换正式/测试源的场景。

修改后的代码如下:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const connectingIp = request.headers.get("cf-connecting-ip");
  // 替换成你的测试源站主机名
  const testOriginHost = "test.yourdomain.com";
  // 替换成你的正式源站主机名(可选,若默认用Worker绑定的域名可省略)
  const prodOriginHost = "www.yourdomain.com";

  let newRequest = request;
  
  if (connectingIp === '185.X.X.X') {
    console.log('内部请求已切换至测试源站');
    // 创建新请求,通过cf.resolveOverride指定测试源站
    newRequest = new Request(request, {
      cf: {
        resolveOverride: testOriginHost
      }
    });
  } else {
    // 可选:为正式请求指定源站,确保所有外部请求指向正式环境
    newRequest = new Request(request, {
      cf: {
        resolveOverride: prodOriginHost
      }
    });
  }

  try {
    const response = await fetch(newRequest);
    console.log(`源站响应状态码:${response.status}`);
    return response;
  } catch (error) {
    console.error('请求源站失败:', error);
    return new Response('服务暂时不可用', { status: 500 });
  }
}

为什么推荐这种方式?

  • 不需要修改请求的完整URL,保持原请求的路径、参数等不变,只切换后端源站
  • 更贴合Cloudflare的网络架构,解析效率更高

方法二:直接修改Request的URL(适合跨域名切换)

如果你的测试站是完全独立的域名,也可以直接修改请求的URL地址:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const connectingIp = request.headers.get("cf-connecting-ip");
  const requestUrl = new URL(request.url);

  // 判断是否为内部IP请求,修改目标主机名
  if (connectingIp === '185.X.X.X') {
    console.log('内部请求已切换至测试源站');
    requestUrl.hostname = "test.yourdomain.com";
  }

  // 创建新的Request对象,使用修改后的URL
  const newRequest = new Request(requestUrl, {
    method: request.method,
    headers: request.headers,
    body: request.body,
    redirect: request.redirect
  });

  const response = await fetch(newRequest);
  return response;
}

额外注意事项

  • IP判断扩展:如果需要允许多个内部IP访问测试站,可以把IP放在数组里,用includes判断,比如:
    const allowedInternalIps = ['185.X.X.X', '192.168.1.100', '10.0.0.5'];
    if (allowedInternalIps.includes(connectingIp)) {
      // 切换到测试源站
    }
    
  • cf-connecting-ip的可靠性:这个请求头是Cloudflare自动添加的,只有当请求经过Cloudflare网络时才会存在,本地测试时可能需要使用Cloudflare的wrangler dev工具模拟,或者部署后再测试。
  • 错误处理:添加try-catch块可以避免源站请求失败导致Worker崩溃,返回更友好的错误响应。

内容的提问来源于stack exchange,提问作者Ben

火山引擎 最新活动