您的代码混合了两种方法,需要做一些调整。我看到有几个问题:
映射格式不一致 :有些值有 http:// 前缀,有些没有
DNS记录需要先设置 :backend1.thanx.top 和 backend2.thanx.top 需要先在DNS中设置A记录指向 106.15.4.153
重定向和内容替换逻辑需要更新 :现在只检查 106.15.4.153,但可能还有其他IP
让我帮您修正代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 export default { async fetch (request, env ) { const domainMappings = { 'test.thanx.top' : 'http://backend1.thanx.top:8085' , 'api.thanx.top' : 'http://backend2.thanx.top:8086' , 'admin.thanx.top' : 'http://backend3.thanx.top:8087' , 'reverse-proxy.yuebinliu.workers.dev' : 'http://backend1.thanx.top:8085' }; const targetIPs = ['106.15.4.153' ]; const url = new URL (request.url ); const target = domainMappings[url.hostname ]; if (!target) { return new Response ('域名未配置: ' + url.hostname + '\n\n已配置的域名: ' + Object .keys (domainMappings).join (', ' ), { status : 404 , headers : { 'Content-Type' : 'text/plain; charset=utf-8' } }); } const targetUrl = new URL (url.pathname + url.search , target); const newHeaders = new Headers (request.headers ); newHeaders.set ('X-Forwarded-Host' , url.hostname ); newHeaders.set ('X-Forwarded-Proto' , url.protocol .replace (':' , '' )); newHeaders.set ('X-Real-IP' , request.headers .get ('cf-connecting-ip' ) || 'unknown' ); const targetHost = new URL (target).hostname ; newHeaders.set ('Host' , targetHost); try { let response = await fetch (targetUrl.toString (), { method : request.method , headers : newHeaders, body : request.body , redirect : 'manual' }); if ([301 , 302 , 303 , 307 , 308 ].includes (response.status )) { const location = response.headers .get ('location' ); if (location) { let newLocation = location; for (const ip of targetIPs) { newLocation = newLocation.replace ( new RegExp (`http://${ip} :\\d+` , 'g' ), `https://${url.hostname} ` ); } if (newLocation !== location) { const newResponse = new Response (response.body , response); newResponse.headers .set ('location' , newLocation); return newResponse; } } } const contentType = response.headers .get ('content-type' ) || '' ; if (contentType.includes ('text/html' )) { let html = await response.text (); for (const ip of targetIPs) { html = html.replace ( new RegExp (`http://${ip} :\\d+` , 'g' ), `https://${url.hostname} ` ); } return new Response (html, { status : response.status , headers : response.headers }); } return response; } catch (error) { return new Response (`代理错误: ${error.message} \n\n目标URL: ${targetUrl.toString()} ` , { status : 502 , headers : { 'Content-Type' : 'text/plain; charset=utf-8' } }); } } }
在部署此代码前,您需要:
在DNS中设置A记录 :
backend1.thanx.top → 106.15.4.153 (DNS only - 灰色云)
backend2.thanx.top → 106.15.4.153 (DNS only - 灰色云)
backend3.thanx.top → 106.15.4.153 (DNS only - 灰色云)
确保后端服务器配置 :
后端服务器需要能够接受这些域名的请求
SSL证书需要对这些域名有效(或者使用HTTP)
如果您不想设置额外的DNS记录,可以使用这个简化版本: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 export default { async fetch (request ) { const domainMappings = { 'test.thanx.top' : { ip : '106.15.4.153' , port : '8085' }, 'api.thanx.top' : { ip : '106.15.4.153' , port : '8086' }, 'admin.thanx.top' : { ip : '106.15.4.153' , port : '8087' } }; const url = new URL (request.url ); const target = domainMappings[url.hostname ]; if (!target) return new Response ('Not found' , { status : 404 }); const targetUrl = `http://${target.ip} :${target.port} ${url.pathname} ${url.search} ` ; const newHeaders = new Headers (request.headers ); newHeaders.set ('Host' , url.hostname ); newHeaders.set ('X-Forwarded-Host' , url.hostname ); return fetch (targetUrl, { method : request.method , headers : newHeaders, body : request.body , cf : { resolveOverride : target.ip } }); } }
建议先设置DNS记录,然后使用第一个版本的代码,这样最稳定可靠。
时间 : 2025-09-06T01:29:06
👤 用户 cloudflare 谁用works配置反向代理时候,发现无法代理ip地址
时间 : 2025-09-06T01:12:23
🤖 DeepSeek (deepseek-chat) 您好!您遇到的问题非常典型,Cloudflare Workers 在设计上出于安全和架构原因,默认不允许直接代理(即作为反向代理)到裸IP地址 。
这是一个有意为之的限制,而不是一个故障或错误配置。下面我将详细解释原因、变通方案以及最佳实践。
为什么 Cloudflare Workers 不允许代理到 IP 地址?
安全风险(最主要原因) :
SNI 要求 :现代TLS(HTTPS)通信依赖于服务器名称指示(SNI) 。当客户端(这里是Worker)连接到一台服务器时,它必须在TLS握手阶段通过SNI指明它想要连接的主机名。IP地址无法提供有效的主机名信息。
证书验证问题 :目标服务器上的SSL证书是针对域名签发的(例如 example.com)。如果你让Worker访问一个IP地址,Worker在验证SSL证书时,会尝试将IP地址与证书中的域名列表进行匹配,这几乎总是会失败,导致SSL证书验证错误。
规避安全策略 :直接使用IP地址可能会被用来绕过基于域名的安全策略和内容过滤。
架构设计 :
Cloudflare 的网络是为基于域名的路由而构建的。IP地址绕过了Cloudflare的DNS系统和全球智能路由(Argo Smart Routing)等优化功能。
滥用防范 :
禁止IP地址可以防止Worker被滥用来攻击或扫描内网或其他网络资源。
错误信息 当您尝试在 fetch() 或 serviceBinding 中使用IP地址时,通常会遇到以下类似错误:
CF-Workers script will not be able to fetch 123.123.123.123. You should use a hostname instead.
Destination 123.123.123.123 is not allowed.
解决方案和变通方法 虽然不能直接使用 https://192.0.2.1,但有几种方法可以实现您的需求:
方法一:使用域名(最佳实践) 这是最推荐、最符合标准且没有副作用的方法。
为您要代理的IP地址创建一个子域名 。
在该子域名的DNS记录中,设置一个 A 记录,指向您的目标IP地址。
例如 : 您想代理 192.0.2.1,可以创建一个DNS记录:
类型 : A
名称 : my-backend.example.com
内容/目标 : 192.0.2.1
代理状态 : (橙色云)DNS only (灰色云)
在您的Worker代码中,使用这个子域名而不是IP地址。
1 2 3 4 5 6 7 8 9 10 11 export default { async fetch (request ) { const url = new URL (request.url ); url.hostname = 'my-backend.example.com' ; let new_request = new Request (url, request); return fetch (new_request); } };
优点 :
完全符合Worker的安全要求。
可以正常进行TLS/SSL握手和证书验证(只要您的证书对该域名有效)。
是最清晰、最可维护的方案。
方法二:使用 resolveOverride 参数(高级用法) 这是一个非官方但广为人知的“特性”,它允许您通过自定义DNS解析来“绕过”限制。您仍然需要提供一个主机名,但Worker会将其解析到您指定的IP。
在您的 fetch 请求中,添加 cf 属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 export default { async fetch (request ) { const fakeHostname = 'my-target.example.com' ; let new_url = new URL (request.url ); new_url.hostname = fakeHostname; let new_request = new Request (new_url, request); return fetch (new_request, { cf : { resolveOverride : '192.0.2.1' } }); } };
重要注意事项 :
这不是官方API :Cloudflare 并未正式将其纳入文档,其行为在未来可能会改变。
SNI问题依然存在 :resolveOverride 只解决了DNS解析问题,但没有解决SNI问题。发送到目标IP的请求中的SNI头仍然是 my-target.example.com。这意味着:
如果目标IP上的服务器配置了针对 my-target.example.com 的SSL证书,那么一切正常。
如果目标服务器使用的是自签名证书、通配符证书,或者证书与 my-target.example.com 不匹配,您可能需要禁用SSL证书验证(不推荐,有安全风险)。
谨慎使用 :建议仅在开发和测试中使用,生产环境更推荐方法一 。
方法三:禁用SSL验证(极度不推荐) 强烈不建议在生产环境中使用此方法 ,因为它会破坏TLS的安全性,使连接容易受到中间人攻击。
如果您在使用 resolveOverride 时遇到证书错误,可以通过将 insecureSkipVerify 设置为 true 来跳过证书验证(这需要与 resolveOverride 结合使用)。
1 2 3 4 5 6 7 return fetch (new_request, { cf : { resolveOverride : '192.0.2.1' , insecureSkipVerify : true } });
总结
方法
推荐度
说明
为IP绑定域名(方法一)
⭐⭐⭐⭐⭐ 最佳实践
安全、可靠、符合规范,是Cloudflare设计的工作方式。
使用 resolveOverride(方法二)
⭐⭐☆ 临时/高级方案
有效但非官方,需要注意SNI/证书匹配问题。
禁用SSL验证(方法三)
⭐☆☆ 危险,应避免
破坏安全性,仅用于极端情况下的测试。
对于绝大多数用户,请直接采用方法一 。花几分钟时间为您要代理的IP地址设置一个DNS A 记录,可以避免后续无数的麻烦和潜在的安全隐患。
时间 : 2025-09-06T01:12:23
👤 用户 帮我修改下下面的代码。好能够直接代理IP
// Cloudflare Worker 代码 - 多域名反向代理 export default { async fetch(request, env) { // 域名到目标服务器的映射 const domainMappings = { ‘test.thanx.top’: ‘http://106.15.4.153:8085 ‘, ‘api.thanx.top’: ‘http://106.15.4.153:8086 ‘, ‘admin.thanx.top’: ‘http://106.15.4.153:8087 ‘, ‘reverse-proxy.yuebinliu.workers.dev’: ‘http://106.15.4.153:8085 ‘ // 测试用 };
const url = new URL(request.url);
const target = domainMappings[url.hostname];
// 如果域名未配置,返回404
if (!target) {
return new Response('域名未配置: ' + url.hostname + '\n\n已配置的域名: ' + Object.keys(domainMappings).join(', '), {
status: 404,
headers: { 'Content-Type': 'text/plain; charset=utf-8' }
});
}
// 准备转发请求
const targetUrl = new URL(url.pathname + url.search, target);
const newHeaders = new Headers(request.headers);
// 设置代理头
newHeaders.set('X-Forwarded-Host', url.hostname);
newHeaders.set('X-Forwarded-Proto', url.protocol.replace(':', ''));
newHeaders.set('X-Real-IP', request.headers.get('cf-connecting-ip') || 'unknown');
newHeaders.delete('host'); // 删除原始host头
try {
// 转发请求到目标服务器
let response = await fetch(targetUrl.toString(), {
method: request.method,
headers: newHeaders,
body: request.body,
redirect: 'manual' // 手动处理重定向
});
// 处理重定向响应
if ([301, 302, 303, 307, 308].includes(response.status)) {
const location = response.headers.get('location');
if (location && location.includes('106.15.4.153')) {
// 替换重定向地址中的原始IP为代理域名
const newLocation = location.replace(
/http:\/\/106\.15\.4\.153:\d+/g,
`https://${url.hostname}`
);
const newResponse = new Response(response.body, response);
newResponse.headers.set('location', newLocation);
return newResponse;
}
}
// 处理HTML内容,替换其中的链接
const contentType = response.headers.get('content-type') || '';
if (contentType.includes('text/html')) {
let html = await response.text();
// 替换所有原始服务器链接为代理域名
html = html.replace(
/http:\/\/106\.15\.4\.153:\d+/g,
`https://${url.hostname}`
);
// 返回修改后的HTML
return new Response(html, {
status: response.status,
headers: response.headers
});
}
// 对于非HTML内容,直接返回
return response;
} catch (error) {
// 错误处理
return new Response(`代理错误: ${error.message}\n\n目标URL: ${targetUrl.toString()}`, {
status: 502,
headers: { 'Content-Type': 'text/plain; charset=utf-8' }
});
}
} }
时间 : 2025-09-06T01:15:11
🤖 DeepSeek (deepseek-chat) 我来帮您修改代码,使其能够直接代理IP地址。根据Cloudflare Workers的限制,我们需要使用resolveOverride方法来实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 export default { async fetch (request, env ) { const domainMappings = { 'test.thanx.top' : { ip : '106.15.4.153' , port : '8085' }, 'api.thanx.top' : { ip : '106.15.4.153' , port : '8086' }, 'admin.thanx.top' : { ip : '106.15.4.153' , port : '8087' }, 'reverse-proxy.yuebinliu.workers.dev' : { ip : '106.15.4.153' , port : '8085' } }; const url = new URL (request.url ); const targetConfig = domainMappings[url.hostname ]; if (!targetConfig) { return new Response ('域名未配置: ' + url.hostname + '\n\n已配置的域名: ' + Object .keys (domainMappings).join (', ' ), { status : 404 , headers : { 'Content-Type' : 'text/plain; charset=utf-8' } }); } const { ip, port } = targetConfig; const virtualHostname = `target-${ip.replace(/\./g, '-' )} -${port} .proxy.internal` ; const targetUrl = new URL (url.pathname + url.search , `http://${virtualHostname} ` ); if (port) { targetUrl.port = port; } const newHeaders = new Headers (request.headers ); newHeaders.set ('X-Forwarded-Host' , url.hostname ); newHeaders.set ('X-Forwarded-Proto' , url.protocol .replace (':' , '' )); newHeaders.set ('X-Real-IP' , request.headers .get ('cf-connecting-ip' ) || 'unknown' ); newHeaders.set ('Host' , virtualHostname); try { let response = await fetch (targetUrl.toString (), { method : request.method , headers : newHeaders, body : request.body , redirect : 'manual' , cf : { resolveOverride : ip, } }); if ([301 , 302 , 303 , 307 , 308 ].includes (response.status )) { const location = response.headers .get ('location' ); if (location) { const newLocation = location.replace ( new RegExp (`http://${ip} :${port} ` , 'g' ), `https://${url.hostname} ` ); const newResponse = new Response (response.body , response); newResponse.headers .set ('location' , newLocation); return newResponse; } } const contentType = response.headers .get ('content-type' ) || '' ; if (contentType.includes ('text/html' )) { let html = await response.text (); html = html.replace ( new RegExp (`http://${ip} :${port} ` , 'g' ), `https://${url.hostname} ` ); return new Response (html, { status : response.status , headers : response.headers }); } return response; } catch (error) { return new Response (`代理错误: ${error.message} \n\n目标URL: ${targetUrl.toString()} ` , { status : 502 , headers : { 'Content-Type' : 'text/plain; charset=utf-8' } }); } } }
主要修改内容:
修改映射结构 :将映射从字符串改为对象,包含ip和port字段
使用虚拟主机名 :创建了一个虚拟主机名用于SNI握手
添加resolveOverride :在fetch请求中使用cf.resolveOverride将虚拟主机名解析到目标IP
更新正则表达式 :使用动态的IP和端口来构建正则表达式,避免硬编码
注意事项:
SSL证书问题 :如果目标服务器使用自签名证书或证书与虚拟主机名不匹配,可能会遇到SSL错误。在这种情况下,您可能需要取消注释insecureSkipVerify: true,但这会降低安全性。
长期解决方案 :建议为每个服务配置一个子域名(如service1.yourdomain.com)指向目标IP,然后在Worker中使用这些子域名,这样更符合Cloudflare的最佳实践。
测试 :部署后请仔细测试所有功能,特别是重定向和链接替换功能。
这个修改后的代码应该能够成功代理到IP地址,同时保持原有的重定向处理和内容替换功能。
时间 : 2025-09-06T01:15:11
👤 用户 Error 1016 Ray ID: 97a7620810d7a5a0 • 2025-09-05 17:17:55 UTC Origin DNS error What happened? You’ve requested a page on a website (target-106-15-4-153-8085.proxy.internal) that is on the Cloudflare network. Cloudflare is currently unable to resolve your requested domain (target-106-15-4-153-8085.proxy.internal).
Please see https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/error-1016/ for more details.
时间 : 2025-09-06T01:18:41
🤖 DeepSeek (deepseek-chat) 这个错误是因为我使用了虚拟主机名 target-106-15-4-153-8085.proxy.internal,但这个域名实际上不存在,Cloudflare 无法解析它。我们需要换一种方法来解决这个问题。
让我重新修改代码,使用更简单直接的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 export default { async fetch (request, env ) { const domainMappings = { 'test.thanx.top' : { ip : '106.15.4.153' , port : '8085' }, 'api.thanx.top' : { ip : '106.15.4.153' , port : '8086' }, 'admin.thanx.top' : { ip : '106.15.4.153' , port : '8087' }, 'reverse-proxy.yuebinliu.workers.dev' : { ip : '106.15.4.153' , port : '8085' } }; const url = new URL (request.url ); const targetConfig = domainMappings[url.hostname ]; if (!targetConfig) { return new Response ('域名未配置: ' + url.hostname + '\n\n已配置的域名: ' + Object .keys (domainMappings).join (', ' ), { status : 404 , headers : { 'Content-Type' : 'text/plain; charset=utf-8' } }); } const { ip, port } = targetConfig; const targetBaseUrl = `http://${ip} :${port} ` ; const targetUrl = new URL (url.pathname + url.search , targetBaseUrl); const newHeaders = new Headers (request.headers ); newHeaders.set ('X-Forwarded-Host' , url.hostname ); newHeaders.set ('X-Forwarded-Proto' , url.protocol .replace (':' , '' )); newHeaders.set ('X-Real-IP' , request.headers .get ('cf-connecting-ip' ) || 'unknown' ); newHeaders.set ('Host' , url.hostname ); try { let response = await fetch (targetUrl.toString (), { method : request.method , headers : newHeaders, body : request.body , redirect : 'manual' , cf : { resolveOverride : ip, } }); if ([301 , 302 , 303 , 307 , 308 ].includes (response.status )) { const location = response.headers .get ('location' ); if (location && location.includes (ip)) { const newLocation = location.replace ( new RegExp (`http://${ip} :${port} ` , 'g' ), `https://${url.hostname} ` ); const newResponse = new Response (response.body , response); newResponse.headers .set ('location' , newLocation); return newResponse; } } const contentType = response.headers .get ('content-type' ) || '' ; if (contentType.includes ('text/html' )) { let html = await response.text (); html = html.replace ( new RegExp (`http://${ip} :${port} ` , 'g' ), `https://${url.hostname} ` ); return new Response (html, { status : response.status , headers : response.headers }); } return response; } catch (error) { return new Response (`代理错误: ${error.message} \n\n目标URL: ${targetUrl.toString()} ` , { status : 502 , headers : { 'Content-Type' : 'text/plain; charset=utf-8' } }); } } }
如果仍然遇到问题,这里是一个更简单的版本: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 export default { async fetch (request, env ) { const domainMappings = { 'test.thanx.top' : '106.15.4.153:8085' , 'api.thanx.top' : '106.15.4.153:8086' , 'admin.thanx.top' : '106.15.4.153:8087' , 'reverse-proxy.yuebinliu.workers.dev' : '106.15.4.153:8085' }; const url = new URL (request.url ); const target = domainMappings[url.hostname ]; if (!target) { return new Response ('域名未配置' , { status : 404 }); } const [ip, port] = target.split (':' ); const targetUrl = `http://${ip} :${port} ${url.pathname} ${url.search} ` ; const newHeaders = new Headers (request.headers ); newHeaders.set ('Host' , url.hostname ); newHeaders.set ('X-Forwarded-Host' , url.hostname ); newHeaders.set ('X-Forwarded-Proto' , 'https' ); newHeaders.set ('X-Real-IP' , request.headers .get ('cf-connecting-ip' ) || '' ); try { const response = await fetch (targetUrl, { method : request.method , headers : newHeaders, body : request.body , cf : { resolveOverride : ip } }); return response; } catch (error) { return new Response (`代理错误: ${error.message} ` , { status : 502 }); } } }
如果还是不行,建议采用最佳实践:
为每个服务创建DNS记录 :
backend1.yourdomain.com → 106.15.4.153 (端口8085)
backend2.yourdomain.com → 106.15.4.153 (端口8086)
等等…
然后在Worker中使用这些域名 :
1 2 3 4 5 const domainMappings = { 'test.thanx.top' : 'backend1.yourdomain.com:8085' , 'api.thanx.top' : 'backend2.yourdomain.com:8086' , };
这样既符合Cloudflare的安全要求,又能稳定工作。
时间 : 2025-09-06T01:18:41
👤 用户 这样吗? // Cloudflare Worker 代码 - 多域名反向代理 export default { async fetch(request, env) { // 域名到目标服务器的映射 const domainMappings = { ‘test.thanx.top’: ‘backend1.thanx.top:8085’, ‘api.thanx.top’: ‘backend2.thanx.top:8086’, ‘admin.thanx.top’: ‘http://106.15.4.153:8087 ‘, ‘reverse-proxy.yuebinliu.workers.dev’: ‘http://backend1.thanx.top:8085 ‘ // 测试用 };
const url = new URL(request.url);
const target = domainMappings[url.hostname];
// 如果域名未配置,返回404
if (!target) {
return new Response('域名未配置: ' + url.hostname + '\n\n已配置的域名: ' + Object.keys(domainMappings).join(', '), {
status: 404,
headers: { 'Content-Type': 'text/plain; charset=utf-8' }
});
}
// 准备转发请求
const targetUrl = new URL(url.pathname + url.search, target);
const newHeaders = new Headers(request.headers);
// 设置代理头
newHeaders.set('X-Forwarded-Host', url.hostname);
newHeaders.set('X-Forwarded-Proto', url.protocol.replace(':', ''));
newHeaders.set('X-Real-IP', request.headers.get('cf-connecting-ip') || 'unknown');
newHeaders.delete('host'); // 删除原始host头
try {
// 转发请求到目标服务器
let response = await fetch(targetUrl.toString(), {
method: request.method,
headers: newHeaders,
body: request.body,
redirect: 'manual' // 手动处理重定向
});
// 处理重定向响应
if ([301, 302, 303, 307, 308].includes(response.status)) {
const location = response.headers.get('location');
if (location && location.includes('106.15.4.153')) {
// 替换重定向地址中的原始IP为代理域名
const newLocation = location.replace(
/http:\/\/106\.15\.4\.153:\d+/g,
`https://${url.hostname}`
);
const newResponse = new Response(response.body, response);
newResponse.headers.set('location', newLocation);
return newResponse;
}
}
// 处理HTML内容,替换其中的链接
const contentType = response.headers.get('content-type') || '';
if (contentType.includes('text/html')) {
let html = await response.text();
// 替换所有原始服务器链接为代理域名
html = html.replace(
/http:\/\/106\.15\.4\.153:\d+/g,
`https://${url.hostname}`
);
// 返回修改后的HTML
return new Response(html, {
status: response.status,
headers: response.headers
});
}
// 对于非HTML内容,直接返回
return response;
} catch (error) {
// 错误处理
return new Response(`代理错误: ${error.message}\n\n目标URL: ${targetUrl.toString()}`, {
status: 502,
headers: { 'Content-Type': 'text/plain; charset=utf-8' }
});
}
} }
时间 : 2025-09-06T01:29:06
🤖 DeepSeek (deepseek-chat) 您的代码混合了两种方法,需要做一些调整。我看到有几个问题:
映射格式不一致 :有些值有 http:// 前缀,有些没有
DNS记录需要先设置 :backend1.thanx.top 和 backend2.thanx.top 需要先在DNS中设置A记录指向 106.15.4.153
重定向和内容替换逻辑需要更新 :现在只检查 106.15.4.153,但可能还有其他IP
让我帮您修正代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 export default { async fetch (request, env ) { const domainMappings = { 'test.thanx.top' : 'http://backend1.thanx.top:8085' , 'api.thanx.top' : 'http://backend2.thanx.top:8086' , 'admin.thanx.top' : 'http://backend3.thanx.top:8087' , 'reverse-proxy.yuebinliu.workers.dev' : 'http://backend1.thanx.top:8085' }; const targetIPs = ['106.15.4.153' ]; const url = new URL (request.url ); const target = domainMappings[url.hostname ]; if (!target) { return new Response ('域名未配置: ' + url.hostname + '\n\n已配置的域名: ' + Object .keys (domainMappings).join (', ' ), { status : 404 , headers : { 'Content-Type' : 'text/plain; charset=utf-8' } }); } const targetUrl = new URL (url.pathname + url.search , target); const newHeaders = new Headers (request.headers ); newHeaders.set ('X-Forwarded-Host' , url.hostname ); newHeaders.set ('X-Forwarded-Proto' , url.protocol .replace (':' , '' )); newHeaders.set ('X-Real-IP' , request.headers .get ('cf-connecting-ip' ) || 'unknown' ); const targetHost = new URL (target).hostname ; newHeaders.set ('Host' , targetHost); try { let response = await fetch (targetUrl.toString (), { method : request.method , headers : newHeaders, body : request.body , redirect : 'manual' }); if ([301 , 302 , 303 , 307 , 308 ].includes (response.status )) { const location = response.headers .get ('location' ); if (location) { let newLocation = location; for (const ip of targetIPs) { newLocation = newLocation.replace ( new RegExp (`http://${ip} :\\d+` , 'g' ), `https://${url.hostname} ` ); } if (newLocation !== location) { const newResponse = new Response (response.body , response); newResponse.headers .set ('location' , newLocation); return newResponse; } } } const contentType = response.headers .get ('content-type' ) || '' ; if (contentType.includes ('text/html' )) { let html = await response.text (); for (const ip of targetIPs) { html = html.replace ( new RegExp (`http://${ip} :\\d+` , 'g' ), `https://${url.hostname} ` ); } return new Response (html, { status : response.status , headers : response.headers }); } return response; } catch (error) { return new Response (`代理错误: ${error.message} \n\n目标URL: ${targetUrl.toString()} ` , { status : 502 , headers : { 'Content-Type' : 'text/plain; charset=utf-8' } }); } } }
在部署此代码前,您需要:
在DNS中设置A记录 :
backend1.thanx.top → 106.15.4.153 (DNS only - 灰色云)
backend2.thanx.top → 106.15.4.153 (DNS only - 灰色云)
backend3.thanx.top → 106.15.4.153 (DNS only - 灰色云)
确保后端服务器配置 :
后端服务器需要能够接受这些域名的请求
SSL证书需要对这些域名有效(或者使用HTTP)
如果您不想设置额外的DNS记录,可以使用这个简化版本: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 export default { async fetch (request ) { const domainMappings = { 'test.thanx.top' : { ip : '106.15.4.153' , port : '8085' }, 'api.thanx.top' : { ip : '106.15.4.153' , port : '8086' }, 'admin.thanx.top' : { ip : '106.15.4.153' , port : '8087' } }; const url = new URL (request.url ); const target = domainMappings[url.hostname ]; if (!target) return new Response ('Not found' , { status : 404 }); const targetUrl = `http://${target.ip} :${target.port} ${url.pathname} ${url.search} ` ; const newHeaders = new Headers (request.headers ); newHeaders.set ('Host' , url.hostname ); newHeaders.set ('X-Forwarded-Host' , url.hostname ); return fetch (targetUrl, { method : request.method , headers : newHeaders, body : request.body , cf : { resolveOverride : target.ip } }); } }
建议先设置DNS记录,然后使用第一个版本的代码,这样最稳定可靠。
时间 : 2025-09-06T01:29:06
对话统计