Open dalaolala opened 5 years ago
感谢
注意网址不要带https
// Website you intended to retrieve for users.
const upstream = 'www.google.com'
// Custom pathname for the upstream website.
const upstream_path = '/'
// Website you intended to retrieve for users using mobile devices.
const upstream_mobile = 'www.google.com'
// Countries and regions where you wish to suspend your service.
const blocked_region = ['KP', 'SY', 'PK', 'CU']
// IP addresses which you wish to block from using your service.
const blocked_ip_address = ['0.0.0.0', '127.0.0.1']
// Whether to use HTTPS protocol for upstream address.
const https = true
// Whether to disable cache.
const disable_cache = false
// Replace texts.
const replace_dict = {
'$upstream': '$custom_domain',
'//google.com': ''
}
addEventListener('fetch', event => {
event.respondWith(fetchAndApply(event.request));
})
async function fetchAndApply(request) {
const region = request.headers.get('cf-ipcountry').toUpperCase();
const ip_address = request.headers.get('cf-connecting-ip');
const user_agent = request.headers.get('user-agent');
let response = null;
let url = new URL(request.url);
let url_hostname = url.hostname;
if (https == true) {
url.protocol = 'https:';
} else {
url.protocol = 'http:';
}
if (await device_status(user_agent)) {
var upstream_domain = upstream;
} else {
var upstream_domain = upstream_mobile;
}
url.host = upstream_domain;
if (url.pathname == '/') {
url.pathname = upstream_path;
} else {
url.pathname = upstream_path + url.pathname;
}
if (blocked_region.includes(region)) {
response = new Response('Access denied: WorkersProxy is not available in your region yet.', {
status: 403
});
} else if (blocked_ip_address.includes(ip_address)) {
response = new Response('Access denied: Your IP address is blocked by WorkersProxy.', {
status: 403
});
} else {
let method = request.method;
let request_headers = request.headers;
let new_request_headers = new Headers(request_headers);
new_request_headers.set('Host', upstream_domain);
new_request_headers.set('Referer', url.protocol + '//' + url_hostname);
let original_response = await fetch(url.href, {
method: method,
headers: new_request_headers
})
connection_upgrade = new_request_headers.get("Upgrade");
if (connection_upgrade && connection_upgrade.toLowerCase() == "websocket") {
return original_response;
}
let original_response_clone = original_response.clone();
let original_text = null;
let response_headers = original_response.headers;
let new_response_headers = new Headers(response_headers);
let status = original_response.status;
if (disable_cache) {
new_response_headers.set('Cache-Control', 'no-store');
}
new_response_headers.set('access-control-allow-origin', '*');
new_response_headers.set('access-control-allow-credentials', true);
new_response_headers.delete('content-security-policy');
new_response_headers.delete('content-security-policy-report-only');
new_response_headers.delete('clear-site-data');
if (new_response_headers.get("x-pjax-url")) {
new_response_headers.set("x-pjax-url", response_headers.get("x-pjax-url").replace("//" + upstream_domain, "//" + url_hostname));
}
const content_type = new_response_headers.get('content-type');
if (content_type != null && content_type.includes('text/html') && content_type.includes('UTF-8')) {
original_text = await replace_response_text(original_response_clone, upstream_domain, url_hostname);
} else {
original_text = original_response_clone.body
}
response = new Response(original_text, {
status,
headers: new_response_headers
})
}
return response;
}
async function replace_response_text(response, upstream_domain, host_name) {
let text = await response.text()
var i, j;
for (i in replace_dict) {
j = replace_dict[i]
if (i == '$upstream') {
i = upstream_domain
} else if (i == '$custom_domain') {
i = host_name
}
if (j == '$upstream') {
j = upstream_domain
} else if (j == '$custom_domain') {
j = host_name
}
let re = new RegExp(i, 'g')
text = text.replace(re, j);
}
return text;
}
async function device_status(user_agent_info) {
var agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
var flag = true;
for (var v = 0; v < agents.length; v++) {
if (user_agent_info.indexOf(agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
}
点击Workers 和 Page
点击创建应用程序
点击创建Worker
部署Worker
编辑代码
复制代码
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
// 准备反代的目的域名,域名自己更改为想要的
let target_url = "https://hostloc.com";
// 要替换内容的正则表达式
let target_url_reg = /hostloc\.com/g;
async function handleRequest(request) {
let url = new URL(request.url);
url.hostname = new URL(target_url).hostname;
// 复制请求对象并更新它的属性
let headers = new Headers(request.headers);
headers.set("Referer", target_url);
headers.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36");
const param = {
method: request.method,
headers: headers,
body: request.body,
redirect: "manual"
}
let response = await fetch(url, param);
// 检查响应头中的内容类型
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('text')) {
// 如果是文本类型,替换响应主体中的URL
let responseBody = await response.text();
responseBody = await handleResBody(request,responseBody);
// 复制响应对象并更新它的属性
let headers = await handleResHeader(response);
return new Response(responseBody, {
status: response.status,
statusText: response.statusText,
headers: headers
});
} else {
// 如果不是文本类型,直接返回响应对象
return response;
}
}
async function handleResBody(request, responseBody){
responseBody = responseBody.replace(target_url_reg, new URL(request.url).hostname);
responseBody = responseBody.replace("<head>", '<head>\n<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">');
responseBody = responseBody.replace("</head>", '<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/gh/lifespy/css-and-js-hub/css/responsive.css">\n</head>');
responseBody = responseBody.replace("</body>", '<script src="//cdn.jsdelivr.net/gh/lifespy/css-and-js-hub/js/polish.js" type="text/javascript"></script>\n</body>');
return responseBody;
}
async function handleResHeader(resp){
let headers = new Headers(resp.headers);
headers.set('Access-Control-Allow-Origin', '*');
headers.set('Access-Control-Allow-Methods', 'GET');
headers.set('Access-Control-Allow-Headers', 'Content-Type');
return headers;
}
点击保存并部署
选择已经接入到Cloudflare的域名
选择DNS,添加如下解析
选择Worker路由
选择添加路由
添加一个路由
点击Production
添加自定义域
至此已经ok,默认的worker域名已被屏蔽,如验证,请科学访问
大佬牛逼
请教一个问题,如果想替换 meta标签,应该怎么实现呢?
代码库在这里
只需要修改index.js 即可
https://github.com/Siujoeng-Lau/Workers-Proxy/blob/master/src/index.js
这里说一下修改步骤
使用cloudflare的Workers
【Create a Worker】然后复制上面的index.js内容即可
使用自定义域名
1、把域名接入cloudflare,此处步骤省略
2、设置子域名关联workers的【add route】
3、设置子域名的cname到workers给出的子域名(这个子域名可以自定义前缀)
3、设置要关联的子域名,此处一定要用这种格式,否则会不好用
选择要使用的子域名以及workers
注意