给网站加了大陆地区的CDN加速

· 记录

在Nodeseek中了一份09cdn的亚太地区的CDN加速套餐,于是想折腾一下,具体思路是:

  1. 大陆地区应用09cdn加速
  2. 其他地区依然使用Cloudflare的大善人解析

思路确定后,便考虑使用Cloudflare Worker实现分区域CDN加速,具体折腾过程如下:

第1步:配置目标CDN

在09cdn控制台中,添加需要加速的域名 bb.bins.fyi,完成源站配置后得到一个CNAME记录值,比如bb.09cdn.com.

第2步:Cloudflare DNS的关键设置(两步)

这是整个方案的关键,包含两条重要的DNS记录:

  1. 主域名A记录(橙色云朵):

    • 类型: A
    • 名称: bb
    • 地址: 指向真实的源站服务器IP地址
    • 代理状态: 必须是“已代理”(橙色云朵)
    • 说明:这条记录是整个分流方案的入口。开启代理后,所有对bb的请求都会先被导向Cloudflare的边缘网络,从而触发Worker。这里的IP地址是Worker在处理非中国大陆流量,或Worker执行失败时的最终回源地址,因此必须是真实的源站IP。
  2. 代理CNAME记录(灰色云朵):

    • 类型: CNAME
    • 名称: cdn (这个子域名可自取,作用是作为区内代理)
    • 目标: bb.09cdn.com (指向在第1步中获取的CNAME)
    • 代理状态: 必须是“仅限DNS”(灰色云朵)

第3步:编写并部署Cloudflare Worker脚本

这是实现智能分流的核心:

/**
 * Cloudflare Worker for Geo-based CDN Routing
 * - FINAL VERSION -
 * - Correctly modifies the RESPONSE headers returned to the browser.
 * - Uses an in-zone CNAME for resolveOverride to satisfy security policy.
 * - Includes try...catch for robustness.
 */
// v5 - Production Ready
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event))
})

async function handleRequest(event) {
  try {
    const request = event.request;
    // !! 指向您在Cloudflare DNS中创建的灰色云朵CNAME
    const chinaCdnHost = 'bb.09cdn.com'; 
    const mainlandChinaCountryCode = ['CN'];
    
    // 从Cloudflare请求头中获取国家代码
    const country = request.headers.get('cf-ipcountry');

    let response;

    if (country && mainlandChinaCountryCode.includes(country)) {
      // 1. 发起子请求到上游服务 (目标CDN)
      const upstreamResponse = await fetch(request, {
        cf: {
          resolveOverride: chinaCdnHost
        }
      });
      
      // 2. 基于上游响应创建一个可修改的响应副本
      response = new Response(upstreamResponse.body, upstreamResponse);
      
      // 3. 在这个返回给浏览器的新响应上添加标记
      response.headers.set('X-Worker-Routed-By', 'China-CDN-Router');
      
    } else {
      // 对于非中国大陆地区,流程相同
      const upstreamResponse = await fetch(request);
      response = new Response(upstreamResponse.body, upstreamResponse);
      response.headers.set('X-Worker-Routed-By', 'Global-Default');
    }
    
    // 4. 返回最终修改过的响应给浏览器
    return response;

  } catch (error) {
    console.error('Worker Error:', error);
    // 如果发生任何错误,返回一个明确的错误信息
    return new Response(`Worker script failed: ${error.message}`, {
      status: 500,
      headers: { 'X-Worker-Error': 'True' }
    });
  }
}

第4步:绑定路由并验证

  1. 绑定路由:在Cloudflare仪表板中,为Worker添加一条路由规则,将 bb.bins.fyi/* 指向刚刚创建的Worker。
  2. 验证:使用全球节点测试工具(如17CE、boce.com),访问 bb.bins.fyi,并检查HTTP响应头。
    • 中国大陆节点应返回 x-worker-routed-by: China-CDN-Router
    • 海外节点应返回 x-worker-routed-by: Global-Default

调试过程中遇到一些坑点

坑点1:Error 526与resolveOverride的安全陷阱

坑点2:Worker脚本的“静默崩溃”

本文作者: 𝓬𝓸𝓵𝓪 🚀
本文链接: https://bb.bins.fyi/archives/30/
最后修改:
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!