国内访问GitHub太慢了,经常遇到加载超时、图片无法显示等问题,严重影响开发效率和使用体验。为解决这个问题,可以尝试使用Cloudflare反向代理GitHub 也有可能会更加慢

实现步骤

1. 创建Cloudflare Worker

  1. 登录Cloudflare账号,点击导航栏的「计算和AI」,然后选择「Workers 和 Pages」
  2. 点击「创建应用程序」,选择「创建Worker」
  3. 选择默认的hello world项目
  4. 这里随便命名,不要出现GitHub防止被抓到,点击「部署」按钮

2. 替换Worker代码

  1. 部署完成后,点击「编辑代码」按钮
  2. 删除默认的worker.js内容,替换为以下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// 域名映射配置
const domain_mappings = {
"github.com": "gh.",
"avatars.githubusercontent.com": "avatars-githubusercontent-com.",
"github.githubassets.com": "github-githubassets-com.",
"collector.github.com": "collector-github-com.",
"api.github.com": "api-github-com.",
"raw.githubusercontent.com": "raw-githubusercontent-com.",
"gist.githubusercontent.com": "gist-githubusercontent-com.",
"github.io": "github-io.",
"assets-cdn.github.com": "assets-cdn-github-com.",
"cdn.jsdelivr.net": "cdn.jsdelivr-net.",
"securitylab.github.com": "securitylab-github-com.",
"www.githubstatus.com": "www-githubstatus-com.",
"npmjs.com": "npmjs-com.",
"git-lfs.github.com": "git-lfs-github-com.",
"githubusercontent.com": "githubusercontent-com.",
"github.global.ssl.fastly.net": "github-global-ssl-fastly-net.",
"api.npms.io": "api-npms-io.",
"github.community": "github-community.",
};

// 需要重定向的路径
const redirect_paths = ["/", "/login", "/signup", "/copilot"];

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

async function handleRequest(request) {
const url = new URL(request.url);
const current_host = url.host;

// 检测Host头,优先使用Host头中的域名来决定后缀
const host_header = request.headers.get("Host");
const effective_host = host_header || current_host;

// 检查特殊路径重定向
if (redirect_paths.includes(url.pathname)) {
return Response.redirect("https://www.gov.cn", 302);
}

// 强制使用 HTTPS
if (url.protocol === "http:") {
url.protocol = "https:";
return Response.redirect(url.href);
}

// 从有效主机名中提取前缀
const host_prefix = getProxyPrefix(effective_host);
if (!host_prefix) {
return new Response("Domain not configured for proxy", { status: 404 });
}

// 根据前缀找到对应的原始域名
let target_host = null;
for (const [original, prefix] of Object.entries(domain_mappings)) {
if (prefix === host_prefix) {
target_host = original;
break;
}
}

if (!target_host) {
return new Response("Domain not configured for proxy", { status: 404 });
}

// 直接使用正则表达式处理最常见的嵌套URL问题
let pathname = url.pathname;

// 修复特定的嵌套URL模式 - 直接移除嵌套URL部分
// 匹配 /xxx/xxx/latest-commit/main/https%3A//gh.xxx.xxx/ 或 /xxx/xxx/tree-commit-info/main/https%3A//gh.xxx.xxx/
pathname = pathname.replace(
/(\/[^\/]+\/[^\/]+\/(?:latest-commit|tree-commit-info)\/[^\/]+)\/https%3A\/\/[^\/]+\/.*/,
"$1"
);

// 同样处理非编码版本
pathname = pathname.replace(
/(\/[^\/]+\/[^\/]+\/(?:latest-commit|tree-commit-info)\/[^\/]+)\/https:\/\/[^\/]+\/.*/,
"$1"
);

// 构建新的请求URL
const new_url = new URL(url);
new_url.host = target_host;
new_url.pathname = pathname;
new_url.protocol = "https:";

// 设置新的请求头
const new_headers = new Headers(request.headers);
new_headers.set("Host", target_host);
new_headers.set("Referer", new_url.href);

try {
// 发起请求
const response = await fetch(new_url.href, {
method: request.method,
headers: new_headers,
body: request.method !== "GET" ? request.body : undefined,
});

// 克隆响应以便处理内容
const response_clone = response.clone();

// 设置新的响应头
const new_response_headers = new Headers(response.headers);
new_response_headers.set("access-control-allow-origin", "*");
new_response_headers.set("access-control-allow-credentials", "true");
new_response_headers.set("cache-control", "public, max-age=14400");
new_response_headers.delete("content-security-policy");
new_response_headers.delete("content-security-policy-report-only");
new_response_headers.delete("clear-site-data");

// 处理响应内容,替换域名引用,使用有效主机名来决定域名后缀
const modified_body = await modifyResponse(
response_clone,
host_prefix,
effective_host
);

return new Response(modified_body, {
status: response.status,
headers: new_response_headers,
});
} catch (err) {
return new Response(`Proxy Error: ${err.message}`, { status: 502 });
}
}

// 获取当前主机名的前缀,用于匹配反向映射
function getProxyPrefix(host) {
// 检查主机名是否以 gh. 开头
if (host.startsWith("gh.")) {
return "gh.";
}

// 检查其他映射前缀
for (const prefix of Object.values(domain_mappings)) {
if (host.startsWith(prefix)) {
return prefix;
}
}

return null;
}

async function modifyResponse(response, host_prefix, effective_hostname) {
// 只处理文本内容
const content_type = response.headers.get("content-type") || "";
if (
!content_type.includes("text/") &&
!content_type.includes("application/json") &&
!content_type.includes("application/javascript") &&
!content_type.includes("application/xml")
) {
return response.body;
}

let text = await response.text();

// 使用有效主机名获取域名后缀部分(用于构建完整的代理域名)
const domain_suffix = effective_hostname.substring(host_prefix.length);

// 替换所有域名引用
for (const [original_domain, proxy_prefix] of Object.entries(
domain_mappings
)) {
const escaped_domain = original_domain.replace(/\./g, "\\.");
const full_proxy_domain = `${proxy_prefix}${domain_suffix}`;

// 替换完整URLs
text = text.replace(
new RegExp(`https?://${escaped_domain}(?=/|"|'|\\s|$)`, "g"),
`https://${full_proxy_domain}`
);

// 替换协议相对URLs
text = text.replace(
new RegExp(`//${escaped_domain}(?=/|"|'|\\s|$)`, "g"),
`//${full_proxy_domain}`
);
}

// 处理相对路径,使用有效主机名
if (host_prefix === "gh.") {
text = text.replace(
/(?<=["'])\/(?!\/|[a-zA-Z]+:)/g,
`https://${effective_hostname}/`
);
}

return text;
}

  1. 点击「部署」按钮完成部署

3. 绑定域和路由

  1. 进入Cloudflare控制面板,选择已添加的域名

  2. 点击左侧导航栏的「计算和AI」,然后选择「Workers 和 Pages」>「路由」>「添加路由」

  3. 按照以下规则绑定域名:

    • JS文件中存在域名映射配置,例如:

      1
      2
      3
      "github.com": "gh.",
      "avatars.githubusercontent.com": "avatars-githubusercontent-com.",
      "github.githubassets.com": "github-githubassets-com.",
    • 假设拥有的域名为 yik.at,需要绑定的域名包括:

      1
      2
      3
      gh.yik.at
      avatars-githubusercontent-com.yik.at
      github-githubassets-com.yik.at
    • 以此类推,为所有域名映射配置对应的子域名

参考以下我的配置:

img

4. 注意事项

  • 不要修改代码中的 redirect_paths 数组,因为Cloudflare官方可能会检测到首页、登录页等敏感路径,从而封禁域名
  • 部署完成后,访问 gh.yik.at(将yik.at替换为实际域名)即可通过反向代理访问GitHub
  • 首次访问可能需要等待DNS解析生效
  • 部分功能可能受限,建议仅用于浏览和查看代码

通过以上步骤,即可完成Cloudflare反向代理GitHub的配置,尝试提升访问速度