Created
September 13, 2024 08:57
-
-
Save symant233/b2844cae494f25021df970e12f40b4e4 to your computer and use it in GitHub Desktop.
cf-proxy-ex modification
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
addEventListener('fetch', (event) => { | |
const url = new URL(event.request.url); | |
thisProxyServerUrlHttps = `${url.protocol}//${url.hostname}/`; | |
thisProxyServerUrl_hostOnly = url.host; | |
//console.log(thisProxyServerUrlHttps); | |
//console.log(thisProxyServerUrl_hostOnly); | |
event.respondWith(handleRequest(event.request)); | |
}); | |
const str = '/'; | |
const proxyCookie = '__PROXY_VISITEDSITE__'; | |
const passwordCookieName = '__PROXY_PWD__'; | |
const password = ''; | |
const replaceUrlObj = '__location____'; | |
let thisProxyServerUrlHttps; | |
let thisProxyServerUrl_hostOnly; | |
// const CSSReplace = ["https://", "http://"]; | |
const httpRequestInjection = ` | |
var now = new URL(window.location.href); | |
var base = now.host; | |
var protocol = now.protocol; | |
var nowlink = protocol + "//" + base + "/"; | |
var oriUrlStr = window.location.href.substring(nowlink.length); | |
function isPosEmbed(html, pos) { | |
if (pos > html.length || pos < 0) return false; | |
let start = html.lastIndexOf('<', pos); | |
if (start === -1) start = 0; | |
let end = html.indexOf('>', pos); | |
if (end === -1) end = html.length; | |
let content = html.slice(start + 1, end); | |
if (content.includes(">") || content.includes("<")) { | |
return true; // in content | |
} | |
return false; | |
} | |
const matchList = [[/href=("|')([^"']*)("|')/g, \`href="\`], [/src=("|')([^"']*)("|')/g, \`src="\`]]; | |
function bodyCovToAbs(body, requestPathNow) { | |
var original = []; | |
var target = []; | |
for (var match of matchList) { | |
var setAttr = body.matchAll(match[0]); | |
if (setAttr != null) { | |
for (var replace of setAttr) { | |
if (replace.length == 0) continue; | |
var strReplace = replace[0]; | |
if (!strReplace.includes(base)) { | |
if (!isPosEmbed(body, replace.index)) { | |
var relativePath = strReplace.substring(match[1].toString().length, strReplace.length - 1); | |
if (!relativePath.startsWith("data:") && !relativePath.startsWith("javascript:") && !relativePath.startsWith("chrome") && !relativePath.startsWith("edge")) { | |
try { | |
var absolutePath = nowlink + new URL(relativePath, requestPathNow).href; | |
//body = body.replace(strReplace, match[1].toString() + absolutePath + \`"\`); | |
original.push(strReplace); | |
target.push(match[1].toString() + absolutePath + \`"\`); | |
} catch { | |
// 无视 | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
for (var i = 0; i < original.length; i++) { | |
body = body.replace(original[i], target[i]); | |
} | |
return body; | |
} | |
function removeIntegrityAttributes(body) { | |
return body.replace(/integrity=("|')([^"']*)("|')/g, ''); | |
} | |
//https://stackoverflow.com/questions/14480345/how-to-get-the-nth-occurrence-in-a-string | |
function nthIndex(str, pat, n){ | |
var L= str.length, i= -1; | |
while(n-- && i++<L){ | |
i= str.indexOf(pat, i); | |
if (i < 0) break; | |
} | |
return i; | |
} | |
//https://stackoverflow.com/questions/4292603/replacing-entire-page-including-head-using-javascript | |
function ReplaceContent(newContent) { | |
document.open(); | |
document.write(newContent); | |
document.close(); | |
} | |
var injectJs = \` | |
//information | |
var now = new URL(window.location.href); | |
var base = now.host; | |
var protocol = now.protocol; | |
var nowlink = protocol + "//" + base + "/"; | |
var oriUrlStr = window.location.href.substring(nowlink.length); | |
var oriUrl = new URL(oriUrlStr); | |
var path = now.pathname.substring(1); | |
console.log("***************************----" + path); | |
if(!path.startsWith("http")) path = "https://" + path; | |
var original_host = path.substring(path.indexOf("://") + "://".length); | |
original_host = original_host.split('/')[0]; | |
var mainOnly = path.substring(0, path.indexOf("://")) + "://" + original_host + "/"; | |
//************************************************************************************************************* | |
function changeURL(relativePath){ | |
try{ | |
if(relativePath && relativePath.startsWith(nowlink)) relativePath = relativePath.substring(nowlink.length); | |
if(relativePath && relativePath.startsWith(base + "/")) relativePath = relativePath.substring(base.length + 1); | |
if(relativePath && relativePath.startsWith(base)) relativePath = relativePath.substring(base.length); | |
}catch{ | |
//ignore | |
} | |
try { | |
var absolutePath = new URL(relativePath, path).href; | |
absolutePath = absolutePath.replace(window.location.href, path); | |
absolutePath = absolutePath.replace(encodeURI(window.location.href), path); | |
absolutePath = absolutePath.replace(encodeURIComponent(window.location.href), path); | |
absolutePath = absolutePath.replace(nowlink, mainOnly); | |
absolutePath = absolutePath.replace(nowlink, encodeURI(mainOnly)); | |
absolutePath = absolutePath.replace(nowlink, encodeURIComponent(mainOnly)); | |
absolutePath = absolutePath.replace(nowlink, mainOnly.substring(0,mainOnly.length - 1)); | |
absolutePath = absolutePath.replace(nowlink, encodeURI(mainOnly.substring(0,mainOnly.length - 1))); | |
absolutePath = absolutePath.replace(nowlink, encodeURIComponent(mainOnly.substring(0,mainOnly.length - 1))); | |
absolutePath = absolutePath.replace(base, original_host); | |
absolutePath = nowlink + absolutePath; | |
return absolutePath; | |
} catch (e) { | |
console.log(path + " " + relativePath); | |
return ""; | |
} | |
} | |
//************************************************************************************************************* | |
function networkInject(){ | |
//inject network request | |
var originalOpen = XMLHttpRequest.prototype.open; | |
var originalFetch = window.fetch; | |
XMLHttpRequest.prototype.open = function(method, url, async, user, password) { | |
url = changeURL(url); | |
console.log("R:" + url); | |
return originalOpen.apply(this, arguments); | |
}; | |
window.fetch = function(input, init) { | |
var url; | |
if (typeof input === 'string') { | |
url = input; | |
} else if (input instanceof Request) { | |
url = input.url; | |
} else { | |
url = input; | |
} | |
url = changeURL(url); | |
console.log("R:" + url); | |
if (typeof input === 'string') { | |
return originalFetch(url, init); | |
} else { | |
const newRequest = new Request(url, input); | |
return originalFetch(newRequest, init); | |
} | |
}; | |
console.log("NETWORK REQUEST METHOD INJECTED"); | |
} | |
function windowOpenInject(){ | |
const originalOpen = window.open; | |
// Override window.open function | |
window.open = function (url, name, specs) { | |
let modifiedUrl = changeURL(url); | |
return originalOpen.call(window, modifiedUrl, name, specs); | |
}; | |
console.log("WINDOW OPEN INJECTED"); | |
} | |
//*********************************************************************************************** | |
class ProxyLocation { | |
constructor(originalLocation) { | |
this.originalLocation = originalLocation; | |
} | |
// 方法:重新加载页面 | |
reload(forcedReload) { | |
this.originalLocation.reload(forcedReload); | |
} | |
// 方法:替换当前页面 | |
replace(url) { | |
this.originalLocation.replace(changeURL(url)); | |
} | |
// 方法:分配一个新的 URL | |
assign(url) { | |
this.originalLocation.assign(changeURL(url)); | |
} | |
// 属性:获取和设置 href | |
get href() { | |
return oriUrlStr; | |
} | |
set href(url) { | |
this.originalLocation.href = changeURL(url); | |
} | |
// 属性:获取和设置 protocol | |
get protocol() { | |
return this.originalLocation.protocol; | |
} | |
set protocol(value) { | |
this.originalLocation.protocol = changeURL(value); | |
} | |
// 属性:获取和设置 host | |
get host() { | |
console.log("********************host"); | |
return original_host; | |
} | |
set host(value) { | |
console.log("********************s host"); | |
this.originalLocation.host = changeURL(value); | |
} | |
// 属性:获取和设置 hostname | |
get hostname() { | |
console.log("********************hostname"); | |
return oriUrl.hostname; | |
} | |
set hostname(value) { | |
console.log("s hostname"); | |
this.originalLocation.hostname = changeURL(value); | |
} | |
// 属性:获取和设置 port | |
get port() { | |
return oriUrl.port; | |
} | |
set port(value) { | |
this.originalLocation.port = value; | |
} | |
// 属性:获取和设置 pathname | |
get pathname() { | |
console.log("********************pathname"); | |
return oriUrl.pathname; | |
} | |
set pathname(value) { | |
console.log("********************s pathname"); | |
this.originalLocation.pathname = value; | |
} | |
// 属性:获取和设置 search | |
get search() { | |
console.log("********************search"); | |
console.log(oriUrl.search); | |
return oriUrl.search; | |
} | |
set search(value) { | |
console.log("********************s search"); | |
this.originalLocation.search = value; | |
} | |
// 属性:获取和设置 hash | |
get hash() { | |
return oriUrl.hash; | |
} | |
set hash(value) { | |
this.originalLocation.hash = value; | |
} | |
// 属性:获取 origin | |
get origin() { | |
return oriUrl.origin; | |
} | |
} | |
//******************************************************************************************** | |
function documentLocationInject(){ | |
Object.defineProperty(document, 'URL', { | |
get: function () { | |
return oriUrlStr; | |
}, | |
set: function (url) { | |
document.URL = changeURL(url); | |
} | |
}); | |
Object.defineProperty(document, '${replaceUrlObj}', { | |
get: function () { | |
return new ProxyLocation(window.location); | |
}, | |
set: function (url) { | |
window.location.href = changeURL(url); | |
} | |
}); | |
console.log("LOCATION INJECTED"); | |
} | |
function windowLocationInject() { | |
Object.defineProperty(window, '${replaceUrlObj}', { | |
get: function () { | |
return new ProxyLocation(window.location); | |
}, | |
set: function (url) { | |
window.location.href = changeURL(url); | |
} | |
}); | |
console.log("WINDOW LOCATION INJECTED"); | |
} | |
function historyInject(){ | |
const originalPushState = History.prototype.pushState; | |
const originalReplaceState = History.prototype.replaceState; | |
History.prototype.pushState = function (state, title, url) { | |
var u = new URL(url, now.href).href; | |
return originalPushState.apply(this, [state, title, u]); | |
}; | |
History.prototype.replaceState = function (state, title, url) { | |
console.log("****************************************************************************") | |
console.log(nowlink); | |
console.log(url); | |
console.log(now.href); | |
var u = new URL(url, now.href).href; | |
console.log(u); | |
return originalReplaceState.apply(this, [state, title, u]); | |
}; | |
console.log("HISTORY INJECTED"); | |
} | |
//************************************************************************************************************* | |
function obsPage() { | |
if (document.body) { | |
var yProxyObserver = new MutationObserver(function(mutations) { | |
mutations.forEach(function(mutation) { | |
traverseAndConvert(mutation); | |
}); | |
}); | |
var config = { attributes: true, childList: true, subtree: true }; | |
yProxyObserver.observe(document.body, config); | |
console.log("OBSERVING THE WEBPAGE..."); | |
} else { | |
console.error("obsPage - document.body is not available."); | |
} | |
} | |
function traverseAndConvert(node) { | |
if (node instanceof HTMLElement) { | |
removeIntegrityAttributesFromElement(node); | |
covToAbs(node); | |
node.querySelectorAll('*').forEach(function(child) { | |
removeIntegrityAttributesFromElement(child); | |
covToAbs(child); | |
}); | |
} | |
} | |
function covToAbs(element) { | |
var relativePath = ""; | |
var setAttr = ""; | |
if (element instanceof HTMLElement && element.hasAttribute("href")) { | |
relativePath = element.getAttribute("href"); | |
setAttr = "href"; | |
} | |
if (element instanceof HTMLElement && element.hasAttribute("src")) { | |
relativePath = element.getAttribute("src"); | |
setAttr = "src"; | |
} | |
// Check and update the attribute if necessary | |
if (setAttr !== "" && relativePath.indexOf(nowlink) != 0) { | |
if (!relativePath.includes("*")) { | |
if (!relativePath.startsWith("data:") && !relativePath.startsWith("javascript:") && !relativePath.startsWith("chrome") && !relativePath.startsWith("edge")) { | |
try { | |
var absolutePath = changeURL(relativePath); | |
console.log(absolutePath); | |
element.setAttribute(setAttr, absolutePath); | |
} catch (e) { | |
console.log(path + " " + relativePath); | |
} | |
} | |
} | |
} | |
} | |
function removeIntegrityAttributesFromElement(element){ | |
if (element.hasAttribute('integrity')) { | |
element.removeAttribute('integrity'); | |
} | |
} | |
//************************************************************************************************************* | |
function loopAndConvertToAbs(){ | |
for(var ele of document.querySelectorAll('*')){ | |
removeIntegrityAttributesFromElement(ele); | |
covToAbs(ele); | |
} | |
console.log("LOOPED EVERY ELEMENT"); | |
} | |
function covScript(){ //由于observer经过测试不会hook添加的script标签,也可能是我测试有问题? | |
var scripts = document.getElementsByTagName('script'); | |
for (var i = 0; i < scripts.length; i++) { | |
covToAbs(scripts[i]); | |
} | |
setTimeout(covScript, 3000); | |
} | |
//************************************************************************************************************* | |
networkInject(); | |
windowOpenInject(); | |
documentLocationInject(); | |
windowLocationInject(); | |
// historyInject(); | |
// 这里实在无能为力不想改,可以pr一个 | |
//window.addEventListener('load', () => { | |
//前端注入本段script是在onload的时候,所以就不用再加事件了,触发不了 | |
//}); | |
//console.log("WINDOW ONLOAD EVENT ADDED"); | |
document.addEventListener('DOMContentLoaded', function() { | |
loopAndConvertToAbs(); | |
console.log("CONVERTED SCRIPT PATH"); | |
obsPage(); | |
covScript(); | |
}); | |
console.log("DOMContentLoaded EVENT ADDED"); | |
window.addEventListener('error', event => { | |
var element = event.target || event.srcElement; | |
if (element.tagName === 'SCRIPT') { | |
console.log('Found problematic script:', element); | |
// 调用 covToAbs 函数 | |
//removeIntegrityAttributesFromElement(element); | |
//covToAbs(element); | |
// 创建新的 script 元素 | |
//var newScript = document.createElement('script'); | |
//newScript.src = element.src; | |
//newScript.async = element.async; // 保留原有的 async 属性 | |
//newScript.defer = element.defer; // 保留原有的 defer 属性 | |
// 添加新的 script 元素到 document | |
//document.head.appendChild(newScript); | |
//console.log('New script added:', newScript); | |
} | |
}, true); | |
console.log("WINDOW CORS ERROR EVENT ADDED"); | |
\`; | |
//addEventListener("load", (event) => { | |
//}); | |
fetch(window.location.href, { | |
method: 'GET', | |
headers: { | |
'real_req': '1' | |
} | |
}) | |
.then(response => response.text()) | |
.then(data => { | |
var wholepage = data; | |
var bd = wholepage.substring(wholepage.indexOf("<" + "!--cf-proxy-ex---***SCRIPT INJECT STOP HERE***---github.com/1234567Yang/cf-proxy-ex-->")); | |
console.log(bd); | |
bd = bodyCovToAbs(bd, oriUrlStr); | |
bd = removeIntegrityAttributes(bd); | |
ReplaceContent("<" + "script>" + injectJs + "<" + "/script>" + bd); | |
}) | |
.catch(error => { | |
console.error('Error while sending request:', error); // 错误处理 | |
}); | |
`; | |
const mainPage = 'forbidden'; | |
const redirectError = ` | |
<html><head></head><body><h2>Error while redirecting: the website you want to access to may contain wrong redirect information, and we can not parse the info</h2></body></html> | |
`; | |
//new URL(请求路径, base路径).href; | |
async function handleRequest(request) { | |
//获取所有cookie | |
const siteCookie = request.headers.get('Cookie'); | |
if (password != '') { | |
if (siteCookie != null && siteCookie != '') { | |
const pwd = getCook(passwordCookieName, siteCookie); | |
console.log(pwd); | |
if (pwd != null && pwd != '') { | |
if (pwd != password) { | |
return getHTMLResponse( | |
'<h1>403 Forbidden</h1><br>You do not have access to view this webpage.' | |
); | |
} | |
} else { | |
return getHTMLResponse( | |
'<h1>403 Forbidden</h1><br>You do not have access to view this webpage.' | |
); | |
} | |
} else { | |
return getHTMLResponse( | |
'<h1>403 Forbidden</h1><br>You do not have access to view this webpage.' | |
); | |
} | |
} | |
const url = new URL(request.url); | |
// if (request.url.endsWith('favicon.ico')) { | |
// return Response.redirect('https://www.baidu.com/favicon.ico', 301); | |
// } | |
//var siteOnly = url.pathname.substring(url.pathname.indexOf(str) + str.length); | |
const actualUrlStr = | |
url.pathname.substring(url.pathname.indexOf(str) + str.length) + | |
url.search + | |
url.hash; | |
if (actualUrlStr == '') { | |
//先返回引导界面 | |
return getHTMLResponse(mainPage); | |
} | |
try { | |
let test = actualUrlStr; | |
if (!test.startsWith('http')) { | |
test = 'https://' + test; | |
} | |
const u = new URL(test); | |
if (!u.host.includes('.')) { | |
throw new Error(); | |
} | |
} catch { | |
//可能是搜素引擎,比如proxy.com/https://www.duckduckgo.com/ 转到 proxy.com/?q=key | |
let lastVisit; | |
if (siteCookie != null && siteCookie != '') { | |
lastVisit = getCook(proxyCookie, siteCookie); | |
console.log(lastVisit); | |
if (lastVisit != null && lastVisit != '') { | |
//(!lastVisit.startsWith("http"))?"https://":"" + | |
//现在的actualUrlStr如果本来不带https:// 的话那么现在也不带,因为判断是否带protocol在后面 | |
return Response.redirect( | |
thisProxyServerUrlHttps + lastVisit + '/' + actualUrlStr, | |
301 | |
); | |
} | |
} | |
return getHTMLResponse( | |
'Something is wrong while trying to get your cookie: <br> siteCookie: ' + | |
siteCookie + | |
'<br>' + | |
'lastSite: ' + | |
lastVisit | |
); | |
} | |
if (!actualUrlStr.startsWith('http') && !actualUrlStr.includes('://')) { | |
//从www.xxx.com转到https://www.xxx.com | |
//actualUrlStr = "https://" + actualUrlStr; | |
return Response.redirect( | |
thisProxyServerUrlHttps + 'https://' + actualUrlStr, | |
301 | |
); | |
} | |
//if(!actualUrlStr.endsWith("/")) actualUrlStr += "/"; | |
const actualUrl = new URL(actualUrlStr); | |
const clientHeaderWithChange = new Headers(); | |
//***代理发送数据的Header:修改部分header防止403 forbidden,要先修改, 因为添加Request之后header是只读的(***ChatGPT,未测试) | |
for (const pair of request.headers.entries()) { | |
//console.log(pair[0]+ ': '+ pair[1]); | |
clientHeaderWithChange.set( | |
pair[0], | |
pair[1] | |
.replaceAll(thisProxyServerUrlHttps, actualUrlStr) | |
.replaceAll(thisProxyServerUrl_hostOnly, actualUrl.host) | |
); | |
} | |
let clientRequestBodyWithChange; | |
if (request.body) { | |
clientRequestBodyWithChange = await request.text(); | |
clientRequestBodyWithChange = clientRequestBodyWithChange | |
.replaceAll(thisProxyServerUrlHttps, actualUrlStr) | |
.replaceAll(thisProxyServerUrl_hostOnly, actualUrl.host); | |
} | |
const modifiedRequest = new Request(actualUrl, { | |
headers: clientHeaderWithChange, | |
method: request.method, | |
body: request.body ? clientRequestBodyWithChange : request.body, | |
//redirect: 'follow' | |
redirect: 'manual', | |
//因为有时候会 | |
//https://www.jyshare.com/front-end/61 重定向到 | |
//https://www.jyshare.com/front-end/61/ | |
//但是相对目录就变了 | |
}); | |
//console.log(actualUrl); | |
const response = await fetch(modifiedRequest); | |
if ( | |
response.status.toString().startsWith('3') && | |
response.headers.get('Location') != null | |
) { | |
//console.log(base_url + response.headers.get("Location")) | |
try { | |
return Response.redirect( | |
thisProxyServerUrlHttps + | |
new URL(response.headers.get('Location'), actualUrlStr).href, | |
301 | |
); | |
} catch { | |
getHTMLResponse( | |
redirectError + | |
'<br>the redirect url:' + | |
response.headers.get('Location') + | |
';the url you are now at:' + | |
actualUrlStr | |
); | |
} | |
} | |
let modifiedResponse; | |
let bd; | |
const contentType = response.headers.get('Content-Type'); | |
if (contentType && contentType.startsWith('text/')) { | |
bd = await response.text(); | |
//ChatGPT | |
const regex = new RegExp(`(?<!src="|href=")(https?:\\/\\/[^s'"]+)`, 'g'); | |
bd = bd.replace(regex, (match) => { | |
if (match.includes('http')) { | |
return thisProxyServerUrlHttps + match; | |
} else { | |
return thisProxyServerUrl_hostOnly + '/' + match; | |
} | |
}); | |
//console.log(bd); // 输出替换后的文本 | |
if ( | |
contentType && | |
(contentType.includes('text/html') || | |
contentType.includes('text/javascript')) | |
) { | |
bd = bd.replace('window.location', 'window.' + replaceUrlObj); | |
bd = bd.replace('document.location', 'document.' + replaceUrlObj); | |
} | |
//bd.includes("<html") //不加>因为html标签上可能加属性 这个方法不好用因为一些JS中竟然也会出现这个字符串 | |
//也需要加上这个方法因为有时候server返回json也是html | |
if ( | |
contentType && | |
contentType.includes('text/html') && | |
bd.includes('<html') | |
) { | |
if (!request.headers.has('real_req')) { | |
return getHTMLResponse( | |
'<html><head><script>' + | |
httpRequestInjection + | |
'</script></head></html>' | |
); | |
} | |
//console.log("STR" + actualUrlStr) | |
bd = | |
'<!--cf-proxy-ex---***SCRIPT INJECT STOP HERE***---github.com/1234567Yang/cf-proxy-ex-->' + | |
bd; | |
} | |
//else{ | |
// //const type = response.headers.get('Content-Type');type == null || (type.indexOf("image/") == -1 && type.indexOf("application/") == -1) | |
// if(actualUrlStr.includes(".css")){ //js不用,因为我已经把网络消息给注入了 | |
// for(var r of CSSReplace){ | |
// bd = bd.replace(r, thisProxyServerUrlHttps + r); | |
// } | |
// } | |
// //问题:在设置css background image 的时候可以使用相对目录 | |
// } | |
//console.log(bd); | |
modifiedResponse = new Response(bd, response); | |
} else { | |
const blob = await response.blob(); | |
modifiedResponse = new Response(blob, response); | |
} | |
const headers = modifiedResponse.headers; | |
const cookieHeaders = []; | |
// Collect all 'Set-Cookie' headers regardless of case | |
for (const [key, value] of headers.entries()) { | |
if (key.toLowerCase() == 'set-cookie') { | |
cookieHeaders.push({ headerName: key, headerValue: value }); | |
} | |
} | |
if (cookieHeaders.length > 0) { | |
cookieHeaders.forEach((cookieHeader) => { | |
const cookies = cookieHeader.headerValue | |
.split(',') | |
.map((cookie) => cookie.trim()); | |
for (let i = 0; i < cookies.length; i++) { | |
const parts = cookies[i].split(';').map((part) => part.trim()); | |
//console.log(parts); | |
// Modify Path | |
const pathIndex = parts.findIndex((part) => | |
part.toLowerCase().startsWith('path=') | |
); | |
let originalPath; | |
if (pathIndex !== -1) { | |
originalPath = parts[pathIndex].substring('path='.length); | |
} | |
const absolutePath = '/' + new URL(originalPath, actualUrlStr).href; | |
if (pathIndex !== -1) { | |
parts[pathIndex] = `Path=${absolutePath}`; | |
} else { | |
parts.push(`Path=${absolutePath}`); | |
} | |
// Modify Domain | |
const domainIndex = parts.findIndex((part) => | |
part.toLowerCase().startsWith('domain=') | |
); | |
if (domainIndex !== -1) { | |
parts[domainIndex] = `domain=${thisProxyServerUrl_hostOnly}`; | |
} else { | |
parts.push(`domain=${thisProxyServerUrl_hostOnly}`); | |
} | |
cookies[i] = parts.join('; '); | |
} | |
// Re-join cookies and set the header | |
headers.set(cookieHeader.headerName, cookies.join(', ')); | |
}); | |
} | |
//bd != null && bd.includes("<html") | |
if ( | |
contentType && | |
contentType.includes('text/html') && | |
response.status == 200 && | |
bd.includes('<html') | |
) { | |
//如果是HTML再加cookie,因为有些网址会通过不同的链接添加CSS等文件 | |
const cookieValue = | |
proxyCookie + | |
'=' + | |
actualUrl.origin + | |
'; Path=/; Domain=' + | |
thisProxyServerUrl_hostOnly; | |
//origin末尾不带/ | |
//例如:console.log(new URL("https://www.baidu.com/w/s?q=2#e")); | |
//origin: "https://www.baidu.com" | |
headers.append('Set-Cookie', cookieValue); | |
} | |
// 添加允许跨域访问的响应头 | |
modifiedResponse.headers.set('Access-Control-Allow-Origin', '*'); | |
//modifiedResponse.headers.set("Content-Security-Policy", "default-src *; script-src * 'unsafe-inline' 'unsafe-eval'; style-src * 'unsafe-inline'; img-src * data:; media-src *; frame-src *; font-src *; connect-src *; base-uri *; form-action *;"); | |
if (modifiedResponse.headers.has('Content-Security-Policy')) { | |
modifiedResponse.headers.delete('Content-Security-Policy'); | |
} | |
if (modifiedResponse.headers.has('Permissions-Policy')) { | |
modifiedResponse.headers.delete('Permissions-Policy'); | |
} | |
modifiedResponse.headers.set('X-Frame-Options', 'ALLOWALL'); | |
return modifiedResponse; | |
} | |
//https://stackoverflow.com/questions/5142337/read-a-javascript-cookie-by-name | |
function getCook(cookiename, cookies) { | |
// Get name followed by anything except a semicolon | |
const cookiestring = RegExp(cookiename + '=[^;]+').exec(cookies); | |
// Return everything after the equal sign, or an empty string if the cookie name not found | |
return decodeURIComponent( | |
cookiestring ? cookiestring.toString().replace(/^[^=]+./, '') : '' | |
); | |
} | |
function getHTMLResponse(html) { | |
return new Response(html, { | |
headers: { | |
'Content-Type': 'text/html; charset=utf-8', | |
}, | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment