林青枫
1
加速后的效果如图
一、cloudflare上创建两个二级域名
一个是你要加速的,真正要访问的域名(bbs),这个域名指向优选域名(www.visa.cn)记住不能开启小黄云。
一个是中继的域名,指向你的服务器的ip的网站服务(ebbs)
做好有关的服务器设置。
二、cloudflare上创建一个worker
创建并且部署,编辑代码
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
// 定义前端展示地址与后端实际地址
const displayHost = "bbs.aaa.com";
const backendHost = "ebbs.aaaa.com";
// 获取原始请求 URL
let originalUrl = new URL(request.url);
// 构造后端请求的 URL,保留路径和查询参数
let backendUrl = new URL(originalUrl);
backendUrl.hostname = backendHost;
// 构造新的请求头,确保传递正确的 Origin 与 Referer
let modifiedHeaders = new Headers(request.headers);
// 可选:删除以下头信息以避免问题
modifiedHeaders.delete("Accept-Encoding");
modifiedHeaders.delete("content-length");
modifiedHeaders.set("origin", "https://" + displayHost);
modifiedHeaders.set("referer", "https://" + displayHost);
// 创建新的请求,针对非 GET/HEAD 方法传递请求体
let newRequest = new Request(backendUrl.href, {
method: request.method,
headers: modifiedHeaders,
body: request.method !== 'GET' && request.method !== 'HEAD' ? request.body : null,
redirect: 'manual'
});
// 发起后端请求
let response = await fetch(newRequest);
// 如果响应内容是文本类型,则将后端地址替换为前端展示地址
const contentType = response.headers.get("content-type") || "";
if (
contentType.includes("text/html") ||
contentType.includes("text/css") ||
contentType.includes("application/javascript")
) {
let text = await response.text();
// 替换所有后端域名为前端域名
text = text.replace(/ebbs\.aaaa\.com/g, displayHost);
return new Response(text, {
status: response.status,
headers: response.headers
});
}
return response;
}
里面有三处需要替换前后端网址,前端是你要访问的加速的域名,后端是中继域名,修改这三个地方,并且部署。
三 添加路由、实现加速
按照步骤添加路由
区域选择你的域名,路由填写
也就是你要展示给大家的,你要加速的网站地址,添加就加速完成了
四、优选IP 推荐
gur.gov.ua
www.visa.com
www.visa.com.sg
www.visa.com.hk
www.visa.com.tw
www.visa.co.jp
www.visakorea.com
www.gco.gov.qa
www.gov.se
www.gov.ua
www.digitalocean.com
www.csgo.com
www.shopify.com
www.whoer.net
www.whatismyip.com
www.ipget.net
www.hugedomains.com
www.udacity.com
www.4chan.org
www.okcupid.com
www.glassdoor.com
www.udemy.com
www.baipiao.eu.org
林青枫
2
最有意思的一个优选域名网站
gur.gov.ua
这个网站是乌克兰的网站,但是在国内的访问速度是所有网站里面最快的,全部一片深绿,真实奇怪,本网站现在正在用这个域名加速。
林青枫
3
addEventListener("fetch", event => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
// 定义前端展示地址与后端实际地址
const displayHost = "blog.isufe.me"; // 你的前端展示域名
const backendHost = "blog.starorigin.cc"; // 你的后端实际域名
// 获取原始请求 URL
let originalUrl = new URL(request.url);
// 构造后端请求的 URL,保留路径和查询参数
let backendUrl = new URL(originalUrl);
backendUrl.hostname = backendHost;
// 构造新的请求头,确保传递正确的 Origin 与 Referer,并修改 Host
let modifiedHeaders = new Headers(request.headers);
// 可选:删除以下头信息以避免问题
modifiedHeaders.delete("Accept-Encoding");
modifiedHeaders.delete("content-length");
// 设置 Origin 和 Referer 为前端展示域名,模拟从前端发起
modifiedHeaders.set("origin", "https://" + displayHost);
modifiedHeaders.set("referer", "https://" + displayHost);
// 重要:将 Host 头设置为后端域名,让后端服务器认为是在访问它自己的域名
modifiedHeaders.set("host", backendHost);
// 创建新的请求,针对非 GET/HEAD 方法传递请求体
let newRequest = new Request(backendUrl.href, {
method: request.method,
headers: modifiedHeaders,
// 对于 GET 或 HEAD 方法,body 必须为 null 或 undefined
body: request.method !== 'GET' && request.method !== 'HEAD' ? request.body : null,
redirect: 'manual' // 不自动跟随重定向,以便我们可以拦截和修改
});
// 发起后端请求
let response = await fetch(newRequest);
// --- 新增:处理后端返回的重定向 (3xx 状态码) ---
if (response.status >= 300 && response.status < 400) {
const location = response.headers.get('Location');
if (location) {
try {
const redirectUrl = new URL(location);
// 检查重定向地址是否包含后端域名
if (redirectUrl.hostname === backendHost) {
// 将重定向地址中的后端域名替换为前端域名
redirectUrl.hostname = displayHost;
const newLocation = redirectUrl.toString();
// 创建新的响应头,复制原始响应头,并更新 Location
const newHeaders = new Headers(response.headers);
newHeaders.set('Location', newLocation);
// 返回一个新的重定向响应给客户端浏览器
// 注意:重定向响应通常没有body,所以第一个参数是null
return new Response(null, {
status: response.status, // 保留原始重定向状态码 (如 301, 302)
statusText: response.statusText,
headers: newHeaders // 使用修改过的headers
});
}
} catch (e) {
// 如果 Location header 不是一个有效的 URL,或者处理出错,记录错误并返回原始响应
console.error("Error processing redirect Location header:", location, e);
// Fallback: 尝试简单的字符串替换(不太安全,但可能有效)
if (location.includes(backendHost)) {
const newLocation = location.replace(new RegExp(backendHost.replace(/\./g, '\\.'), 'g'), displayHost);
const newHeaders = new Headers(response.headers);
newHeaders.set('Location', newLocation);
return new Response(null, {
status: response.status,
statusText: response.statusText,
headers: newHeaders
});
}
// 如果 fallback 也无效,直接返回原始响应
return response;
}
}
// 如果没有 Location header 或者 Location header 不包含后端域名,直接返回原始重定向响应
return response;
}
// --- 结束重定向处理 ---
// 如果响应内容是文本类型(如 HTML, CSS, JS, JSON),则将后端地址替换为前端展示地址
const contentType = response.headers.get("content-type") || "";
if (
contentType.includes("text/html") ||
contentType.includes("text/css") ||
contentType.includes("application/javascript") ||
contentType.includes("application/json") // 考虑包含 JSON
) {
// 尝试复制响应,以便可以读取body而不会消耗原始响应流
const responseClone = response.clone();
try {
let text = await responseClone.text();
// 替换所有后端域名为前端域名
// 注意正则表达式中的点`.`需要转义`\.`
text = text.replace(new RegExp(backendHost.replace(/\./g, '\\.'), 'g'), displayHost);
// 创建一个新的 Response,使用修改后的文本和原始的headers/status
// 需要复制原始headers,因为headers对象是只读的
const newHeaders = new Headers(response.headers);
// 你可能还需要根据需要修改一些Cache-Control头,避免浏览器缓存原始响应
// 例如:newHeaders.set('Cache-Control', 'no-cache, no-store, must-revalidate');
return new Response(text, {
status: response.status,
statusText: response.statusText,
headers: newHeaders // 使用复制后的headers
});
} catch (e) {
// 如果处理文本失败,返回原始响应
console.error("Error processing text response:", e);
return response;
}
}
// 对于非文本响应,直接返回原始响应
return response;
}
增加了处理后端重定向内容的worker代码,@君,详细解释一下代码的含义,与两者的不同
好的,@君 同学,我们来详细解释一下 @林青枫 最新发布的这段 Cloudflare Worker 代码,并与之前的版本进行比较。
核心目标(两者共有):
这两段代码的核心目标是一致的:创建一个 Cloudflare Worker 作为反向代理。用户访问一个“前端展示域名”(比如 blog.isufe.me
),Worker 拦截这个请求,然后从一个“后端实际域名”(比如 blog.starorigin.cc
)获取内容,并将内容中所有指向“后端实际域名”的链接替换为“前端展示域名”,最后将处理过的内容返回给用户。这样做可以利用 Cloudflare 的全球网络和 CDN 来加速用户对后端实际服务器的访问,特别是对于国内访问可能较慢的服务器。
最新代码的详细解释与改进之处:
我们逐段分析最新代码,并指出相比旧代码的改进:
-
基础设置 (与旧代码类似):
addEventListener("fetch", ...)
: Worker 的标准入口点,监听传入的 HTTP 请求。
handleRequest(request)
: 处理请求的主要异步函数。
displayHost
, backendHost
: 定义了你需要替换成自己域名的两个变量,清晰明了。
-
构造后端请求 URL (与旧代码类似):
- 获取原始请求
originalUrl
。
- 基于
originalUrl
创建 backendUrl
,并将其 hostname
修改为后端实际域名 backendHost
。这确保了请求被发送到正确的源服务器。
-
修改请求头 (关键改进之一):
modifiedHeaders = new Headers(request.headers)
: 复制原始请求头。
modifiedHeaders.delete("Accept-Encoding")
, modifiedHeaders.delete("content-length")
: 这两项与旧代码相同,删除 Accept-Encoding
可以避免 Cloudflare Worker 处理压缩内容的复杂性(让源服务器返回未压缩内容,Worker 处理后再由 Cloudflare CDN 压缩),删除 content-length
是因为如果修改了请求体(虽然这里没改),长度可能会变化。
modifiedHeaders.set("origin", "https://" + displayHost)
, modifiedHeaders.set("referer", "https://" + displayHost)
: 这两项也与旧代码相同,将 Origin 和 Referer 设置为前端展示域名。这可以模拟请求是从前端域名发出的,对于一些有防盗链设置的后端服务可能是必要的。
modifiedHeaders.set("host", backendHost);
(新増且重要): 这是新代码中的一个关键补充。它明确地将发送给后端服务器的 Host
请求头设置为后端的实际域名 (backendHost
)。
- 为什么重要? 很多 Web 服务器(如 Nginx, Apache)使用
Host
头来区分同一个 IP 地址上的不同网站(称为虚拟主机)。如果 Host
头不正确(例如,如果发送的是 displayHost
),后端服务器可能不知道该提供哪个网站的内容,导致返回错误页面或默认页面。旧代码没有设置 Host
头,fetch
默认可能会使用 backendUrl
的 hostname
作为 Host
,或者在某些情况下行为不确定。显式设置 Host: backendHost
确保了后端服务器能正确识别并处理请求。
-
创建并发送新请求 (与旧代码类似,但更健壮):
newRequest = new Request(...)
: 创建发往后端的新请求对象。
body: request.method !== 'GET' && request.method !== 'HEAD' ? request.body : null
: 确保只有在非 GET/HEAD 请求时才传递请求体。
redirect: 'manual'
: 阻止 fetch
自动处理重定向(HTTP 3xx 状态码)。这是必要的,因为我们需要自己处理重定向,以便修改其中的 URL。
response = await fetch(newRequest)
: 向后端服务器发起请求并等待响应。
-
处理后端重定向 (全新功能):
if (response.status >= 300 && response.status < 400)
: 检查后端返回的 HTTP 状态码是否为重定向(如 301, 302, 307 等)。
location = response.headers.get('Location')
: 获取重定向的目标 URL。
try...catch
: 增加了错误处理。如果 Location
头不是有效的 URL,会捕获错误。
redirectUrl = new URL(location)
: 将 Location
字符串解析为 URL 对象。
if (redirectUrl.hostname === backendHost)
: 检查重定向的目标 URL 是否仍然指向后端域名。
redirectUrl.hostname = displayHost
: (核心逻辑) 如果重定向指向后端域名,就将其中的域名替换为前端展示域名。
newLocation = redirectUrl.toString()
: 将修改后的 URL 对象转换回字符串。
newHeaders.set('Location', newLocation)
: 更新响应头中的 Location
字段。
return new Response(null, ...)
: 向用户的浏览器返回一个新的重定向响应,状态码不变,但 Location
头已经被修改为指向前端域名。这样浏览器就会正确地跳转到前端域名的相应路径下,而不是暴露后端域名。
- Fallback (备用方案):
catch
块中增加了一个简单的字符串替换 location.replace(...)
作为备用。这可以在 new URL()
解析失败或域名检查逻辑未覆盖所有情况时尝试进行替换。虽然不如基于 URL 对象的操作精确,但能增加一些容错性。
- 为什么需要这个? 如果后端网站因为某些原因(比如登录后跳转、URL 规范化)返回了重定向响应,并且重定向地址是后端域名,那么旧代码会直接把这个原始重定向返回给浏览器。浏览器就会跳转到后端域名,从而暴露了后端地址,也脱离了 Worker 的加速和域名伪装。新代码解决了这个问题。
-
处理响应内容替换 (改进):
contentType.includes(...)
: 检查响应的 Content-Type
是否为文本类型。新代码增加了对 application/json
的处理,因为 JSON 内容中也可能包含需要替换的 URL。
const responseClone = response.clone();
: (重要改进) 在读取响应体之前克隆了响应对象。response.text()
会消耗掉响应体数据流,一旦读取就不能再读。克隆后,即使 text()
或后续处理出错,原始的 response
对象仍然可用,可以作为 fallback 返回。旧代码直接在原 response
上调用 text()
,如果出错则无法返回原始响应。
try...catch
: 将文本处理逻辑包裹在 try...catch
中,如果替换过程中发生错误(例如读取 text()
失败),则会捕获异常并返回原始的 response
(来自 fetch
的未修改响应)。
text = text.replace(new RegExp(backendHost.replace(/\./g, '\\.'), 'g'), displayHost);
: (更健壮的替换) 使用了正则表达式进行全局替换 (g
标志)。backendHost.replace(/\./g, '\\.')
这部分是为了正确处理域名中的点 (.
),因为点在正则表达式中有特殊含义(匹配任意字符),需要转义 (\.
) 才能精确匹配域名中的点。旧代码使用的是简单的字符串替换,如果 backendHost
包含正则表达式的特殊字符,可能会导致意外替换。
newHeaders = new Headers(response.headers)
: 明确复制原始响应头,并在其基础上创建新响应。
return new Response(text, ...)
: 返回包含修改后文本内容的新响应。
-
返回非文本响应 (与旧代码类似):
- 如果响应内容不是需要处理的文本类型(如图片、视频等),或者文本处理出错,则直接返回从后端获取的原始
response
。
总结:新旧代码的主要区别
特性/功能 |
旧代码 |
新代码 (最新发布) |
优点 (新代码) |
Host 请求头 |
未显式设置 (可能导致后端虚拟主机识别问题) |
显式设置为 backendHost (modifiedHeaders.set("host", backendHost); ) |
提高与后端服务器的兼容性,特别是虚拟主机。 |
重定向处理 |
不处理 (可能将用户重定向到后端域名) |
拦截 3xx 响应,并将 Location 头中的后端域名替换为前端域名 |
保持用户始终在前端域名下,不暴露后端,体验更一致。 |
响应体读取 |
直接读取 response.text() |
使用 response.clone().text() |
更安全,即使读取失败也能返回原始响应。 |
URL 替换 |
简单字符串替换 |
使用 new RegExp(...) 并转义特殊字符 |
更精确、更健壮的域名替换。 |
内容类型处理 |
处理 HTML, CSS, JS |
处理 HTML, CSS, JS, JSON |
覆盖更广,适用于 API 等场景。 |
错误处理 |
有限 |
增加了 try...catch 包裹重定向处理和文本处理逻辑 |
更稳定,遇到异常时能优雅降级,不易完全中断服务。 |
总而言之,@林青枫 最新提供的 Worker 代码是旧代码的一个显著增强版。它通过正确设置 Host
头、智能处理后端重定向、以及采用更健壮的内容替换和错误处理机制,使得基于 Worker 的反向代理方案更加稳定、兼容性更好、用户体验更无缝。 对于需要依赖 Worker 进行网站加速和域名伪装的场景,强烈推荐使用这段更新后的代码。