-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpages-function.js
133 lines (116 loc) · 3.83 KB
/
pages-function.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
// 针对Cloudflare Pages的GitHub镜像 - 使用Pages Functions
export async function onRequest(context) {
const request = context.request;
const url = new URL(request.url);
const path = url.pathname;
const search = url.search;
// 处理预检请求
if (request.method === 'OPTIONS') {
return handleCORS();
}
// 构建转发到GitHub的URL
let githubURL;
let isHTML = false;
let isAPI = false;
let isRaw = false;
let isAsset = false;
// 处理API请求
if (path.startsWith('/api/')) {
githubURL = `https://api.github.com${path.replace('/api', '')}${search}`;
isAPI = true;
}
// 处理raw内容请求
else if (path.startsWith('/raw/')) {
githubURL = `https://raw.githubusercontent.com${path.replace('/raw', '')}${search}`;
isRaw = true;
}
// 处理静态资源请求 (图片, CSS, JS等)
else if (/\.(jpg|jpeg|png|gif|svg|css|js|ico|woff|woff2|ttf|eot)$/i.test(path)) {
githubURL = `https://github.com${path}${search}`;
isAsset = true;
}
// 处理普通GitHub页面请求
else {
githubURL = `https://github.com${path}${search}`;
isHTML = true;
}
// 复制原始请求的头部信息
let headers = new Headers(request.headers);
headers.delete('host');
// 添加必要的头部信息以访问GitHub API
if (isAPI) {
headers.set('Accept', 'application/vnd.github.v3+json');
// 如果环境变量中设置了GitHub令牌,使用它
const githubToken = context.env.GITHUB_TOKEN;
if (githubToken) {
headers.set('Authorization', `token ${githubToken}`);
}
}
// 创建新的请求
let githubRequest = new Request(githubURL, {
method: request.method,
headers: headers,
body: request.body,
redirect: 'follow'
});
try {
// 获取GitHub的响应
let response = await fetch(githubRequest);
// 对于HTML内容,需要重写URL
if (isHTML && response.headers.get('content-type')?.includes('text/html')) {
const text = await response.text();
const modifiedText = rewriteGitHubLinks(text, url.origin);
// 创建新的响应头
let newHeaders = new Headers(response.headers);
newHeaders.set('Access-Control-Allow-Origin', '*');
return new Response(modifiedText, {
status: response.status,
statusText: response.statusText,
headers: newHeaders
});
}
// 创建新的响应头
let newHeaders = new Headers(response.headers);
newHeaders.set('Access-Control-Allow-Origin', '*');
return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: newHeaders
});
} catch (err) {
return new Response(`请求GitHub失败: ${err.message}`, {
status: 500,
headers: { 'Content-Type': 'text/plain;charset=UTF-8' }
});
}
}
/**
* 处理CORS预检请求
*/
function handleCORS() {
return new Response(null, {
status: 204,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Max-Age': '86400'
}
});
}
/**
* 重写HTML中的GitHub链接为代理链接
* @param {string} html HTML内容
* @param {string} proxyOrigin 代理的源地址
* @returns {string} 重写后的HTML
*/
function rewriteGitHubLinks(html, proxyOrigin) {
// 替换绝对链接
html = html.replace(/https:\/\/github\.com\//g, `${proxyOrigin}/`);
html = html.replace(/https:\/\/api\.github\.com\//g, `${proxyOrigin}/api/`);
html = html.replace(/https:\/\/raw\.githubusercontent\.com\//g, `${proxyOrigin}/raw/`);
// 替换相对链接
html = html.replace(/href="\/([^"]*)"/g, `href="${proxyOrigin}/$1"`);
html = html.replace(/src="\/([^"]*)"/g, `src="${proxyOrigin}/$1"`);
return html;
}