-
-
Save noobnooc/d0407b5fb81cff9d36f981170b99d4e6 to your computer and use it in GitHub Desktop.
// Website you intended to retrieve for users. | |
const upstream = 'api.openai.com' | |
// Custom pathname for the upstream website. | |
const upstream_path = '/' | |
// Website you intended to retrieve for users using mobile devices. | |
const upstream_mobile = upstream | |
// Countries and regions where you wish to suspend your service. | |
const blocked_region = [] | |
// 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', | |
} | |
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, | |
body: request.body | |
}) | |
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; | |
} |
测试了,可以使用。
请求时需要设置几个请求头
1.“cf-ipcountry”
2.“cf-connecting-ip”
3.“user-agent”
分别完成 地区黑名单,IP黑名单和客户端设备识别
怎么设置请求头?
你好最后一共请求头填什么
方便说一下嘛?@Hysian
@OceanLcJ 按照我的截图那样填写就行,user-agent 你打开浏览器控制台,里面复制一下你的其他请求的 user-agent 就行
@Hysian 谢谢
Cannot find name 'connection_upgrade'.
Cannot find name 'connection_upgrade'.
一样
复制过来就这样,上图这样,添加标头了还是一样
connection_upgrade 前面加个 var 声明:
var connection_upgrade = new ....
new_response_headers.set('access-control-allow-credentials', true); 这里的 true 要用字符串形式,变成
new_response_headers.set('access-control-allow-credentials', 'true');
connection_upgrade 前面加个 var 声明:
var connection_upgrade = new ....
new_response_headers.set('access-control-allow-credentials', true); 这里的 true 要用字符串形式,变成
new_response_headers.set('access-control-allow-credentials', 'true');
感谢更新,确实解决了部分报警,不过控制台仍然对于 clone() 的使用给出了Warning,认为资源浪费。
"Your worker created multiple branches of a single stream (for instance, by calling response.clone()
or request.clone()
) but did not read the body of both branches. This is wasteful, as it forces the system to buffer the entire stream of data in memory, rather than streaming it through. This may cause your worker to be unexpectedly terminated for going over the memory limit. If you only meant to copy the request or response headers and metadata (e.g. in order to be able to modify them), use the appropriate constructors instead (for instance, new Response(response.body, response)
, new Request(request)
, etc)."
以下代码修复了控制台报Warning,我自己进行了一下测试,没有发现异常。供有需要的朋友参考使用。
https://gist.github.com/Chapoly1305/c2f52e198a7cf870d9c0653c1f4d6a5d/revisions
connection_upgrade 前面加个 var 声明:
var connection_upgrade = new ....
new_response_headers.set('access-control-allow-credentials', true); 这里的 true 要用字符串形式,变成
new_response_headers.set('access-control-allow-credentials', 'true');
感谢更新,确实解决了部分报警,不过控制台仍然对于 clone() 的使用给出了Warning,认为资源浪费。 "Your worker created multiple branches of a single stream (for instance, by calling
response.clone()
orrequest.clone()
) but did not read the body of both branches. This is wasteful, as it forces the system to buffer the entire stream of data in memory, rather than streaming it through. This may cause your worker to be unexpectedly terminated for going over the memory limit. If you only meant to copy the request or response headers and metadata (e.g. in order to be able to modify them), use the appropriate constructors instead (for instance,new Response(response.body, response)
,new Request(request)
, etc)."以下代码修复了控制台报Warning,我自己进行了一下测试,没有发现异常。供有需要的朋友参考使用。 https://gist.github.com/Chapoly1305/c2f52e198a7cf870d9c0653c1f4d6a5d/revisions
非常感谢你,参考了你的js部署一遍就成功了!
给worker使用自定义域名就会导致访问不到。
报 error 1011.
搞了个简单粗暴的解决方案
const region = request.headers.get('cf-ipcountry').toUpperCase();
改成
const region = 'US'
OK
放到 cloudflare word 报错