应用场景:
- 在域名绑定受限制的情况下隐藏原服务器真实地址,
- 没限制直接绑定托管到cf的域名就可以了,
- 比如在境内IDC上部署一个没备案的域名,
- 只支持二级域名的免费空间换成自己的顶级域名
- 家庭宽带没有80 443端口的情况下对外发布应用
- 访问某些被限制访问的网站,例如Google Drive等 注意某些个别网站是不可以用的,还有登录cookie之类的功能会受限制
在cf中找到worker 创建一个部署,部署过程看提示就行,
基本步骤如下,cf后台 右侧点击 workers 概况 创建一个服务 会提示子域什么的哪个按照提示操作
服务名字 我输入 xxx
项目地址 是类似
xxx.你的账户名.workers.dev 的格式,
启动器 我们选择http处理程序
打开后 项目地址 提示 hello word 就是ok了
然后点击快速编辑 在线编辑,删除初始的代码,粘贴下面的 使用js代码格式
//主要配置这个对象
const config = {
basic: {
//源站的url
upstream: 'http://debug.com/',
//对于移动端的源站url
mobileRedirect: 'http://debug.com/',
},
//屏蔽的国家,默认有CN被我删了,否则会返回错误
firewall: {
blockedRegion: ['KP', 'SY', 'PK', 'CU'],
blockedIPAddress: [],
scrapeShield: true,
},
//不同地区源站url的特化
routes: {
TW: 'https://debug.com/',
HK: 'https://debug.com/',
FR: 'https://debug.com/',
},
//下面是压缩和缓存配置
optimization: {
cacheEverything: false,
cacheTtl: 5,
mirage: true,
polish: 'off',
minify: {
javascript: true,
css: true,
html: true,
},
},
};
//检查是不是手机
async function isMobile(userAgent) {
const agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'];
return agents.any((agent) => userAgent.indexOf(agent) > 0);
}
//主函数
async function fetchAndApply(request) {
const region = request.headers.get('cf-ipcountry') || '';
const ipAddress = request.headers.get('cf-connecting-ip') || '';
const userAgent = request.headers.get('user-agent') || '';
request.headers.set("user-agent", "mirror");
//根据屏蔽的国家返回错误
if (region !== '' && config.firewall.blockedRegion.includes(region.toUpperCase())) {
return new Response(
'Access denied: booster.js is not available in your region.',
{
status: 403,
},
);
} if (ipAddress !== '' && config.firewall.blockedIPAddress.includes(ipAddress)) {
return new Response(
'Access denied: Your IP address is blocked by booster.js.',
{
status: 403,
},
);
}
const requestURL = new URL(request.url);
let upstreamURL = null;
//构造请求的url
if (userAgent && isMobile(userAgent) === true) {
upstreamURL = new URL(config.basic.mobileRedirect);
} else if (region && region.toUpperCase() in config.routes) {
upstreamURL = new URL(config.routes[region.toUpperCase()]);
} else {
upstreamURL = new URL(config.basic.upstream);
}
//假如源站url有路径就都加一起
requestURL.protocol = upstreamURL.protocol;
requestURL.host = upstreamURL.host;
requestURL.pathname = upstreamURL.pathname + requestURL.pathname;
//有请求主体的跟没有请求主体的
let newRequest;
if (request.method === 'GET' || request.method === 'HEAD') {
newRequest = new Request(requestURL, {
cf: {
cacheEverything: config.optimization.cacheEverything,
cacheTtl: config.optimization.cacheTtl,
mirage: config.optimization.mirage,
polish: config.optimization.polish,
minify: config.optimization.minify,
scrapeShield: config.firewall.scrapeShield,
},
method: request.method,
headers: request.headers,
});
} else {
const requestBody = await request.text();
newRequest = new Request(requestURL, {
cf: {
cacheEverything: config.optimization.cacheEverything,
cacheTtl: config.optimization.cacheTtl,
mirage: config.optimization.mirage,
polish: config.optimization.polish,
minify: config.optimization.minify,
scrapeShield: config.firewall.scrapeShield,
},
method: request.method,
headers: request.headers,
body: requestBody,
});
}
const fetchedResponse = await fetch(newRequest);
const modifiedResponseHeaders = new Headers(fetchedResponse.headers);
if (modifiedResponseHeaders.has('x-pjax-url')) {
const pjaxURL = new URL(modifiedResponseHeaders.get('x-pjax-url'));
pjaxURL.protocol = requestURL.protocol;
pjaxURL.host = requestURL.host;
pjaxURL.pathname = pjaxURL.path.replace(requestURL.pathname, '/');
modifiedResponseHeaders.set(
'x-pjax-url',
pjaxURL.href,
);
}
return new Response(
fetchedResponse.body,
{
headers: modifiedResponseHeaders,
status: fetchedResponse.status,
statusText: fetchedResponse.statusText,
},
);
}
// eslint-disable-next-line no-restricted-globals
addEventListener('fetch', (event) => {
event.respondWith(fetchAndApply(event.request));
});
另外有一个有意思的代码
#在线浏览器
https://github.com/yangmyc/jsproxy/blob/master/cf-worker/index.js
然后把域名 替换成 我们地址的顶级域名
首先,域名必须托管在cf 并且是dns托管,第三方cname的方式也可以但是更复杂,我这里不在记录。域名增加一条A解析记录,必须是 代理模式 指向的ip随意
下面要注意的是,必须在域名的界面左侧点击 规则 页面规则 ,然后在右侧 再点击 workers
添加
测试后 ok
进阶=》 源站增加密码认证 参考我之前的文章
根据cf请求的heard里面会有 下面五个数据,我们选择 HTTP_CF_WORKER 这个唯一的
HTTP_CF_WORKER:
HTTP_CF_CONNECTING_IP:
HTTP_CF_EW_VIA: 15
HTTP_CF_VISITOR:
HTTP_CF_RAY:
把上文里面的php代码修改一下
// 先判断
if(strpos($My_agent,'mirror') ==false ){
修改为
// 先判断 UA 以及是否是来自cf
if(strpos($_SERVER['HTTP_CF_WORKER'],'leiyanhui.com') ==false && strpos($My_agent,'mirror') ==false) {
另外再把 css js img登图片迁移到 github+jsdelivr
值得注意的是,用户登录要用到的cookie session之类的 反向代理 就别想了。