前言

检查更新通常是一个软件必备的功能,通过 Github Api 可以比较方便的实现更新检查,但是国内的访问比较困难,通过 Cloudflare 加速就显得很有必要了。

实现过程

Github 中的资源分为3块

  • Api
    比如 https://api.github.com/repos/chr233/asfenhance/releases

  • 仓库中的静态文件
    比如 http://raw.githubusercontent.com/chr233/PureNGA/refs/heads/main/.github/aifadian.png

  • Release 中的文件
    比如 https://github.com/chr233/ASFEnhance/releases/download/2.3.12.0/ASFEnhance.zip

Worker 脚本如下

有两种思路, 一种是3种资源使用3个 Worker 处理,这样最简单, 还有一种是在一个 Worker 中一起处理

方案一, 3个 Worker

3个子域名对应3种资源

  • Api

Github 需要设置 ApiToken, 在 Worker 里设置 GH_TOKEN 为自己的 ApiToken 就行

export default {
  async fetch(request, env, ctx) {
    const { GH_TOKEN } = env;

    const { host, pathname } = new URL(request.url);

    if (pathname === '/') {
          return new Response(`this is a mirror of https://api.github.com\r\nsuch as https://api.github.com/repos/chr233/purenga -> https://${host}/purenga`, { status: 200 });
    }

    // GitHub 仓库文件地址
    const github_host = "api.github.com/repos/chr233";
    // 替换 2 次以同时兼容 Worker 来源和域名来源
    const url = request.url.replace(host, github_host);

    const response = await fetch(url, {
      headers: {
        "Authorization": `Bearer ${GH_TOKEN}`,
        "User-Agent": request.headers.get('user-agent'),
        "Referer": request.headers.get('referer'),
      }
    });

    const target_host = "https://github.com/chr233";
    const mirror_host = "https://download.chrxw.com";

    const body = await response.text();

    const new_body = body.replaceAll(target_host, mirror_host)

    return new Response(new_body, response);
  }
}
  • Raw
export default {
  async fetch(request, env, ctx) {
    const { host, pathname } = new URL(request.url);

    if (pathname === '/') {
      return new Response(`this is a mirror of https://raw.githubusercontent.com\r\nsuch as https://raw.githubusercontent.com/chr233/purenga -> https://${host}/purenga`, { status: 200 });
    }

    // GitHub 仓库文件地址
    const github_host = "raw.githubusercontent.com/chr233";
    // 替换 2 次以同时兼容 Worker 来源和域名来源
    const url = request.url.replace(host, github_host);
    return fetch(url, {
      method: request.method,
      headers: {
        "User-Agent": request.headers.get('user-agent'),
        "Referer": request.headers.get('referer'),
      }
    });
  }
}
  • Download
export default {
  async fetch(request, env, ctx) {
    const { host, pathname } = new URL(request.url);

    if (pathname === '/') {
      return new Response(`this is a mirror of https://github.com\r\nsuch as https://github.com/chr233/ASFEnhance/releases/download/2.3.12.0/ASFEnhance.zip -> https://${host}/ASFEnhance/releases/download/2.3.12.0/ASFEnhance.zip`, { status: 200 });
    }

    // GitHub 仓库文件地址
    const github_host = "github.com/chr233";
    // 替换 2 次以同时兼容 Worker 来源和域名来源
    const url = request.url.replace(host, github_host);

    return fetch(url,{
      method: request.method,
      headers: {
        "User-Agent": request.headers.get('user-agent'),
        "Referer": request.headers.get('referer'),
      },
    });
  }
}

方案二, 一个Worker, 按照不同路径代理不同的域名

需要设置 GH_TOKEN, 和 PackageNames

因为代理的仓库所有者为 Xposed-Modules-Repo, 额外添加了仓库名白名单, 只有白名单内的仓库进行反代

PackageNames 示例值: ["com.chrxw.purenga"]

export default {
  async fetch(request, env, ctx) {
    const { PackageNames, GH_TOKEN } = env;

    const { host, pathname } = new URL(request.url);

    if (pathname.startsWith("/dl/")) {
      const entries = pathname.toLowerCase().split('/');

      if (entries.length < 3 || !entries[2]) {
        const demoPackage = PackageNames[0];
        return new Response(`this is a mirror of https://api.github.com, missing packageName, such as: https://${host}/${demoPackage} -> https://api.github.com/repos/Xposed-Modules-Repo/${demoPackage}`, { status: 200 });
      }

      const currentPackageName = entries[2];

      let valid = false;
      for (const name of PackageNames) {
        if (currentPackageName == name) {
          valid = true;
          break;
        }
      }

      if (!valid) {
        return new Response(`this is a mirror of https://api.github.com, deny package name ${currentPackageName}`, { status: 403 });
      }

      // GitHub 仓库文件地址
      const github_host = "github.com/Xposed-Modules-Repo";
      // 替换 2 次以同时兼容 Worker 来源和域名来源
      const url = request.url.replace(host + "/dl", github_host);

      const response = await fetch(url, {
        headers: {
          "User-Agent": request.headers.get('user-agent'),
          "Referer": request.headers.get('referer'),
        }
      });

      return response;
    } else if (pathname.startsWith("/raw/")) {
      const entries = pathname.toLowerCase().split('/');

      if (entries.length < 3 || !entries[2]) {
        const demoPackage = PackageNames[0];
        return new Response(`this is a mirror of https://api.github.com, missing packageName, such as: https://${host}/${demoPackage} -> https://api.github.com/repos/Xposed-Modules-Repo/${demoPackage}`, { status: 200 });
      }

      const currentPackageName = entries[2];

      let valid = false;
      for (const name of PackageNames) {
        if (currentPackageName == name) {
          valid = true;
          break;
        }
      }

      if (!valid) {
        return new Response(`this is a mirror of https://api.github.com, deny package name ${currentPackageName}`, { status: 403 });
      }

      // GitHub 仓库文件地址
      const github_host = "raw.githubusercontent.com/Xposed-Modules-Repo";
      // 替换 2 次以同时兼容 Worker 来源和域名来源
      const url = request.url.replace(host + "/raw", github_host);

      const response = await fetch(url, {
        headers: {
          "User-Agent": request.headers.get('user-agent'),
          "Referer": request.headers.get('referer'),
        }
      });

      return response;
    } else {
      const entries = pathname.toLowerCase().split('/');

      if (entries.length < 2 || !entries[1]) {
        const demoPackage = PackageNames[0];
        return new Response(`this is a mirror of https://api.github.com, missing packageName, such as: https://${host}/${demoPackage} -> https://api.github.com/repos/Xposed-Modules-Repo/${demoPackage}`, { status: 200 });
      }

      const currentPackageName = entries[1];

      let valid = false;
      for (const name of PackageNames) {
        if (currentPackageName == name) {
          valid = true;
          break;
        }
      }

      if (!valid) {
        return new Response(`this is a mirror of https://github.com/, deny package name ${currentPackageName}`, { status: 403 });
      }

      // GitHub 仓库文件地址
      const github_host = "api.github.com/repos/Xposed-Modules-Repo";
      // 替换 2 次以同时兼容 Worker 来源和域名来源
      const url = request.url.replace(host, github_host);

      const response = await fetch(url, {
        headers: {
          "Authorization": `Bearer ${GH_TOKEN}`,
          "User-Agent": request.headers.get('user-agent'),
          "Referer": request.headers.get('referer'),
        }
      });

      const target_host = "https://github.com/Xposed-Modules-Repo";
      const mirror_host = `https://${host}/dl`;

      const body = await response.text()

      const new_body = body.replaceAll(target_host, mirror_host)

      return new Response(new_body, response);
    }
  }
}
最后修改:2025 年 09 月 29 日
如果觉得我的文章对你有用,请随意赞赏