Last active 1725433337

可以设置自己的主页,加快国内Jsd速度,可以作为CDN源站

Revision e17fb0b40aba5af04a3ed1274e64bfb068eb2eab

worker.js Raw
1const upstream = 'cdn.jsdelivr.net'
2const upstream_mobile = 'cdn.jsdelivr.net'
3
4const blocked_region = ['KP', 'RU']
5const blocked_ip_address = ['0.0.0.0', '127.0.0.1']
6
7const replace_dict = {
8 '$upstream': '$custom_domain',
9 '//cdn.jsdelivr.net': ''
10}
11
12addEventListener('fetch', event => {
13 event.respondWith(fetchAndApply(event.request));
14})
15
16async function fetchAndApply(request) {
17 const region = request.headers.get('cf-ipcountry').toUpperCase();
18 const ip_address = request.headers.get('cf-connecting-ip');
19 const user_agent = request.headers.get('user-agent');
20
21 let response = null;
22 let url = new URL(request.url);
23 let url_host = url.host;
24
25 // 检查路径是否不是 /gh/ 或 /npm/ 或 /wp/
26 if (!url.pathname.startsWith('/gh/') && !url.pathname.startsWith('/npm/') && !url.pathname.startsWith('/wp/')) {
27 // 返回简单的 HTML 页面并在 3 秒后重定向到 https://jsd-page.qyliu.top/
28 const htmlContent = `
29 <!DOCTYPE html>
30 <html lang="zh-CN">
31 <head>
32 <meta charset="UTF-8">
33 <meta name="viewport" content="width=device-width, initial-scale=1.0">
34 <title>正在跳转...</title>
35 <style>
36 body {
37 margin: 0;
38 padding: 0;
39 display: flex;
40 justify-content: center;
41 align-items: center;
42 height: 100vh;
43 background-color: #f3f4f6;
44 font-family: Arial, sans-serif;
45 color: #333;
46 }
47 .container {
48 text-align: center;
49 background-color: #fff;
50 padding: 20px;
51 border-radius: 8px;
52 box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
53 }
54 .container h1 {
55 font-size: 24px;
56 margin-bottom: 10px;
57 }
58 .container p {
59 font-size: 16px;
60 color: #666;
61 }
62 </style>
63 <script type="text/javascript">
64 setTimeout(function() {
65 window.location.href = "https://jsd-page.qyliu.top/";
66 }, 3000);
67 </script>
68 </head>
69 <body>
70 <div class="container">
71 <h1>...正在跳转...</h1>
72 <p>该路径禁止访问</p>
73 <p>您将被重定向,请稍候...</p>
74 </div>
75 </body>
76 </html>
77 `;
78 return new Response(htmlContent, {
79 headers: { 'Content-Type': 'text/html' },
80 });
81 }
82
83 if (url.protocol == 'http:') {
84 url.protocol = 'https:'
85 response = Response.redirect(url.href);
86 return response;
87 }
88
89 let upstream_domain;
90
91 if (await device_status(user_agent)) {
92 upstream_domain = upstream
93 } else {
94 upstream_domain = upstream_mobile
95 }
96
97 url.host = upstream_domain;
98
99 if (blocked_region.includes(region)) {
100 response = new Response('Access denied: WorkersProxy is not available in your region yet.', {
101 status: 403
102 });
103 } else if(blocked_ip_address.includes(ip_address)){
104 response = new Response('Access denied: Your IP address is blocked by WorkersProxy.', {
105 status: 403
106 });
107 } else{
108 let method = request.method;
109 let request_headers = request.headers;
110 let new_request_headers = new Headers(request_headers);
111
112 new_request_headers.set('Host', upstream_domain);
113 new_request_headers.set('Referer', url.href);
114
115 let original_response = await fetch(url.href, {
116 method: method,
117 headers: new_request_headers
118 })
119
120 let original_response_clone = original_response.clone();
121 let original_text = null;
122 let response_headers = original_response.headers;
123 let new_response_headers = new Headers(response_headers);
124
125 let status = original_response.status;
126
127 new_response_headers.set('access-control-allow-origin', '*');
128 new_response_headers.set('access-control-allow-credentials', 'true'); // 将 true 转换为字符串
129 new_response_headers.delete('content-security-policy');
130 new_response_headers.delete('content-security-policy-report-only');
131 new_response_headers.delete('clear-site-data');
132
133 const content_type = new_response_headers.get('content-type');
134 if (content_type && content_type.includes('text/html') && content_type.includes('UTF-8')) {
135 original_text = await replace_response_text(original_response_clone, upstream_domain, url_host);
136 } else {
137 original_text = original_response_clone.body;
138 }
139
140 response = new Response(original_text, {
141 status,
142 headers: new_response_headers
143 })
144 }
145 return response;
146}
147
148async function replace_response_text(response, upstream_domain, host_name) {
149 let text = await response.text()
150
151 var i, j;
152 for (i in replace_dict) {
153 j = replace_dict[i]
154 if (i == '$upstream') {
155 i = upstream_domain
156 } else if (i == '$custom_domain') {
157 i = host_name
158 }
159
160 if (j == '$upstream') {
161 j = upstream_domain
162 } else if (j == '$custom_domain') {
163 j = host_name
164 }
165
166 let re = new RegExp(i, 'g')
167 text = text.replace(re, j);
168 }
169 return text;
170}
171
172async function device_status (user_agent_info) {
173 var agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
174 var flag = true;
175 for (var v = 0; v < agents.length; v++) {
176 if (user_agent_info.indexOf(agents[v]) > 0) {
177 flag = false;
178 break;
179 }
180 }
181 return flag;
182}
183