所有文章 → 文章详情

使用 Cloudflare Worker 反向代理单个网站

无用冷知识:本站的评论区依赖此技术运行

由于国内互联网的种种限制,有时访问一些国外资源会比较困难。在每个客户端上均使用代理显然是不现实的,此时,由服务器反向代理目标站点达到加速访问的目的是一种不错的解决方案。
我本为了国内访问者的体验而需要反代 giscus ,找了一圈网上已有的反代脚本都不是非常符合我的需求,才有的这篇文章。

其实在 Cloudflare Worker 上做反代的脚本早就有不少了,但是它们大多都是通用的去反代路径上的 URL,而不是仅限于代理单个域。例如:现有的大多数方案都需要请求revprox.my-domain.com/giscus.app/*来反代giscus.app/*。然而我当只需要代理某一个特定站点时,每次用这样的 URL 请求很难看不说,你自己的反代 Worker 还可能被别人用于反代其他站点,总是不太舒服。

我希望能够将revprox.my-domain.com/*直接反代到giscus.app/*,于是有了以下脚本:

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

async function handleRequest(request) {
  const url = new URL(request.url);
  url.hostname = "giscus.app";
  url.protocol = "https:";

  let response = await fetch(url, {
    method: request.method,
    headers: request.headers,
    body: request.method !== "GET" && request.method !== "HEAD" ? request.body : null,
    redirect: "follow",
  });

  const contentType = response.headers.get("content-type") || "";
  // 直接转发非html内容
  if (!contentType.includes("text/html")) {
    return response;
  }

  // 对html注入脚本
  return new HTMLRewriter()
    .on("head", new InsertScript())
    .transform(response);
}

class InsertScript {
  element(element) {
    element.append(PATCH_SCRIPT, { html: true });
  }
}

const PATCH_SCRIPT = `

`;

本脚本将我的域名直接反代至giscus.app,例如访问https://your.reverse.proxy.domain.com/client.js实际内容与https://giscus.app/client.js一致。同时动态替换登录按钮中的链接以使其重新指向giscus.app。此脚本可以直接复制到 Cloudflare Workers 内使用,如果你正好需要反代giscus那开箱即用,稍作修改也可适配更多网站。

如此一来,单个反代服务只会代理一个目标域,无须担心服务会被别人用作其他站点的反代,也让请求的 URL 变的更加美观。

重要

请不要代理违法站点。Vercel 已经被墙了,Cloudflare 免费域名也已半死不活,这些还能免费使用的服务且用且珍惜。使用此代码时,您始终应遵守地方、州、国家的相关法律及规定。