From f3d4d4f32752c86771fac9436c45617d9fd5175c Mon Sep 17 00:00:00 2001 From: cmliu Date: Wed, 11 Dec 2024 23:38:05 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=91=E5=AE=9A=E5=90=8D=E4=B8=BA'KV'?= =?UTF-8?q?=E7=9A=84KV=E7=A9=BA=E9=97=B4=EF=BC=8C=E5=8D=B3=E5=8F=AF?= =?UTF-8?q?=E5=9C=A8=E9=85=8D=E7=BD=AE=E9=A1=B5=E5=AE=9E=E7=8E=B0=E5=9C=A8?= =?UTF-8?q?=E7=BA=BF=E7=BC=96=E8=BE=91'ADD'=E4=B8=8E'ADDAPI'=E4=BC=98?= =?UTF-8?q?=E9=80=89=E5=88=97=E8=A1=A8=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 + 明文源码.js | 416 +++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 303 insertions(+), 116 deletions(-) diff --git a/README.md b/README.md index ee5d51c..0b66da1 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,9 @@ Telegram交流群:[@CMLiussss](https://t.me/CMLiussss),**感谢[Alice Networ # 注意事项 +### 开启在线编辑优选列表 +- 绑定名为`KV`的KV空间,即可在无`SUB`的前提下,在配置页实现在线编辑`ADD`与`ADDAPI`优选列表; + ### **关于`KEY`与`UUID`:** - 填入`KEY`变量后,将停用`UUID`变量,请确保**二者选其一使用**! 1. 填写`KEY`后,您的**永久订阅**地址为:`https://[YOUR-URL]/[YOUR-KEY]`; diff --git a/明文源码.js b/明文源码.js index af03cfb..5dce8ba 100644 --- a/明文源码.js +++ b/明文源码.js @@ -45,6 +45,7 @@ let userIDTime = ""; let proxyIPPool = []; let path = '/?ed=2560'; let 动态UUID; +let link = []; export default { async fetch(request, env, ctx) { try { @@ -123,7 +124,7 @@ export default { FileName = env.SUBNAME || FileName; subEmoji = env.SUBEMOJI || env.EMOJI || subEmoji; if (subEmoji == '0') subEmoji = 'false'; - + if (env.LINK) link = await 整理(env.LINK) ; sub = env.SUB || sub; subConverter = env.SUBAPI || subConverter; if (subConverter.includes("http://") ){ @@ -160,6 +161,9 @@ export default { } else if (路径 == `/${fakeUserID}`) { const fakeConfig = await 生成配置信息(userID, request.headers.get('Host'), sub, 'CF-Workers-SUB', RproxyIP, url, env); return new Response(`${fakeConfig}`, { status: 200 }); + } else if (路径 == `/${动态UUID}/add` || 路径 == `/${userID}/add`) { + const html = await KV(request, env); + return html; } else if (路径 == `/${动态UUID}` || 路径 == `/${userID}`) { await sendMessage(`#获取订阅 ${FileName}`, request.headers.get('CF-Connecting-IP'), `UA: ${UA}\n域名: ${url.hostname}\n入口: ${url.pathname + url.search}`); const 维列斯Config = await 生成配置信息(userID, request.headers.get('Host'), sub, UA, RproxyIP, url, env); @@ -173,10 +177,10 @@ export default { let total = 24 * 1099511627776 ; if (userAgent && userAgent.includes('mozilla')){ - return new Response(`${维列斯Config}`, { + return new Response(`
${维列斯Config}
`, { status: 200, headers: { - "Content-Type": "text/plain;charset=utf-8", + "Content-Type": "text/html;charset=utf-8", "Profile-Update-Interval": "6", "Subscription-Userinfo": `upload=${pagesSum}; download=${workersSum}; total=${total}; expire=${expire}`, } @@ -730,7 +734,7 @@ async function remoteSocketToWS(remoteSocket, webSocket, 维列斯ResponseHeader function base64ToArrayBuffer(base64Str) { // 如果输入为空,直接返回空结果 if (!base64Str) { - return { error: null }; + return { earlyData: undefined, error: null }; } try { // Go 语言使用了 URL 安全的 Base64 变体(RFC 4648) @@ -751,7 +755,7 @@ function base64ToArrayBuffer(base64Str) { return { earlyData: arryBuffer.buffer, error: null }; } catch (error) { // 如果在任何步骤中出现错误(如非法 Base64 字符),则返回错误 - return { error }; + return { earlyData: undefined, error }; } } @@ -1193,21 +1197,8 @@ function 配置信息(UUID, 域名地址) { 传输层安全 = ['',false]; } - const 威图瑞 = `${协议类型}://${用户ID}@${地址}:${端口}\u003f\u0065\u006e\u0063\u0072\u0079`+'p'+`${atob('dGlvbj0=') + 加密方式}\u0026\u0073\u0065\u0063\u0075\u0072\u0069\u0074\u0079\u003d${传输层安全[0]}&sni=${SNI}&fp=${指纹}&type=${传输层协议}&host=${伪装域名}&path=${encodeURIComponent(路径)}#${encodeURIComponent(别名)}`; - const 猫猫猫 = `- type: ${协议类型} - name: ${FileName} - server: ${地址} - port: ${端口} - uuid: ${用户ID} - network: ${传输层协议} - tls: ${传输层安全[1]} - udp: false - sni: ${SNI} - client-fingerprint: ${指纹} - ws-opts: - path: "${路径}" - headers: - host: ${伪装域名}`; + const 威图瑞 = `${协议类型}://${用户ID}@${地址}:${端口}\u003f\u0065\u006e\u0063\u0072\u0079`+'p'+`${atob('dGlvbj0=') + 加密方式}\u0026\u0073\u0065\u0063\u0075\u0072\u0069\u0074\u0079\u003d${传输层安全[0]}&sni=${SNI}&fp=${指纹}&type=${传输层协议}&host=${伪装域名}&path=${encodeURIComponent(路径)}#${encodeURIComponent(别名)}`; + const 猫猫猫 = `- {name: ${FileName}, server: ${地址}, port: ${端口}, type: ${协议类型}, uuid: ${用户ID}, tls: ${传输层安全[1]}, alpn: [h3], udp: false, sni: ${SNI}, tfo: false, skip-cert-verify: true, servername: ${伪装域名}, client-fingerprint: ${指纹}, network: ${传输层协议}, ws-opts: {path: "${路径}", headers: {${伪装域名}}}}`; return [威图瑞,猫猫猫]; } @@ -1228,46 +1219,64 @@ async function 生成配置信息(userID, hostName, sub, UA, RproxyIP, _url, env } const subs = await 整理(sub); if (subs.length > 1) sub = subs[0]; - - } else if ((addresses.length + addressesapi.length + addressesnotls.length + addressesnotlsapi.length + addressescsv.length) == 0){ - // 定义 Cloudflare IP 范围的 CIDR 列表 - let cfips = [ - '103.21.244.0/23', - '104.16.0.0/13', - '104.24.0.0/14', - '172.64.0.0/14', - '103.21.244.0/23', - '104.16.0.0/14', - '104.24.0.0/15', - '141.101.64.0/19', - '172.64.0.0/14', - '188.114.96.0/21', - '190.93.240.0/21', - ]; - - // 生成符合给定 CIDR 范围的随机 IP 地址 - function generateRandomIPFromCIDR(cidr) { - const [base, mask] = cidr.split('/'); - const baseIP = base.split('.').map(Number); - const subnetMask = 32 - parseInt(mask, 10); - const maxHosts = Math.pow(2, subnetMask) - 1; - const randomHost = Math.floor(Math.random() * maxHosts); - - const randomIP = baseIP.map((octet, index) => { - if (index < 2) return octet; - if (index === 2) return (octet & (255 << (subnetMask - 8))) + ((randomHost >> 8) & 255); - return (octet & (255 << subnetMask)) + (randomHost & 255); - }); - - return randomIP.join('.'); + } else { + if (env.KV){ + const KV空间优选列表 = await env.KV.get('/ADD.txt'); + if (KV空间优选列表) { + const KV空间优选列表数组 = await 整理(KV空间优选列表); + for (const item of KV空间优选列表数组) { + if (item.startsWith('https://')) { + addressesapi.push(item); + } else if (item.includes('://')) { + link.push(item); + } else { + addresses.push(item); + } + } + } } - addresses = addresses.concat('127.0.0.1:1234#CFnat'); - if (hostName.includes(".workers.dev")) { - addressesnotls = addressesnotls.concat(cfips.map(cidr => generateRandomIPFromCIDR(cidr) + '#CF随机节点')); - } else { - addresses = addresses.concat(cfips.map(cidr => generateRandomIPFromCIDR(cidr) + '#CF随机节点')); + + if ((addresses.length + addressesapi.length + addressesnotls.length + addressesnotlsapi.length + addressescsv.length) == 0){ + // 定义 Cloudflare IP 范围的 CIDR 列表 + let cfips = [ + '103.21.244.0/23', + '104.16.0.0/13', + '104.24.0.0/14', + '172.64.0.0/14', + '103.21.244.0/23', + '104.16.0.0/14', + '104.24.0.0/15', + '141.101.64.0/19', + '172.64.0.0/14', + '188.114.96.0/21', + '190.93.240.0/21', + ]; + + // 生成符合给定 CIDR 范围的随机 IP 地址 + function generateRandomIPFromCIDR(cidr) { + const [base, mask] = cidr.split('/'); + const baseIP = base.split('.').map(Number); + const subnetMask = 32 - parseInt(mask, 10); + const maxHosts = Math.pow(2, subnetMask) - 1; + const randomHost = Math.floor(Math.random() * maxHosts); + + const randomIP = baseIP.map((octet, index) => { + if (index < 2) return octet; + if (index === 2) return (octet & (255 << (subnetMask - 8))) + ((randomHost >> 8) & 255); + return (octet & (255 << subnetMask)) + (randomHost & 255); + }); + + return randomIP.join('.'); + } + addresses = addresses.concat('127.0.0.1:1234#CFnat'); + if (hostName.includes(".workers.dev")) { + addressesnotls = addressesnotls.concat(cfips.map(cidr => generateRandomIPFromCIDR(cidr) + '#CF随机节点')); + } else { + addresses = addresses.concat(cfips.map(cidr => generateRandomIPFromCIDR(cidr) + '#CF随机节点')); + } } } + const uuid = (_url.pathname == `/${动态UUID}`) ? 动态UUID : userID; const userAgent = UA.toLowerCase(); const Config = 配置信息(userID , hostName); @@ -1307,73 +1316,86 @@ async function 生成配置信息(userID, hostName, sub, UA, RproxyIP, _url, env let socks5List = ''; if (go2Socks5s.length > 0 && enableSocks ) { socks5List = `${decodeURIComponent('SOCKS5%EF%BC%88%E7%99%BD%E5%90%8D%E5%8D%95%EF%BC%89%3A%20')}`; - if (go2Socks5s.includes(atob('YWxsIGlu'))||go2Socks5s.includes(atob('Kg=='))) socks5List += `${decodeURIComponent('%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F')}\n`; - else socks5List += `\n ${go2Socks5s.join('\n ')}\n`; + if (go2Socks5s.includes(atob('YWxsIGlu'))||go2Socks5s.includes(atob('Kg=='))) socks5List += `${decodeURIComponent('%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F')}
`; + else socks5List += `
  ${go2Socks5s.join('
  ')}
`; } - let 订阅器 = '\n'; + let 订阅器 = '
'; if (sub) { - if (enableSocks) 订阅器 += `CFCDN(访问方式): Socks5\n ${newSocks5s.join('\n ')}\n${socks5List}`; - else if (proxyIP && proxyIP != '') 订阅器 += `CFCDN(访问方式): ProxyIP\n ${proxyIPs.join('\n ')}\n`; - else if (RproxyIP == 'true') 订阅器 += `CFCDN(访问方式): 自动获取ProxyIP\n`; - else 订阅器 += `CFCDN(访问方式): 无法访问, 需要您设置 proxyIP/PROXYIP !!!\n` - 订阅器 += `\nSUB(优选订阅生成器): ${sub}`; + if (enableSocks) 订阅器 += `CFCDN(访问方式): Socks5
  ${newSocks5s.join('
  ')}
${socks5List}`; + else if (proxyIP && proxyIP != '') 订阅器 += `CFCDN(访问方式): ProxyIP
  ${proxyIPs.join('
  ')}
`; + else if (RproxyIP == 'true') 订阅器 += `CFCDN(访问方式): 自动获取ProxyIP
`; + else 订阅器 += `CFCDN(访问方式): 无法访问, 需要您设置 proxyIP/PROXYIP !!!
` + 订阅器 += `
SUB(优选订阅生成器): ${sub}`; } else { - if (enableSocks) 订阅器 += `CFCDN(访问方式): Socks5\n ${newSocks5s.join('\n ')}\n${socks5List}`; - else if (proxyIP && proxyIP != '') 订阅器 += `CFCDN(访问方式): ProxyIP\n ${proxyIPs.join('\n ')}\n`; - else 订阅器 += `CFCDN(访问方式): 无法访问, 需要您设置 proxyIP/PROXYIP !!!\n`; - 订阅器 += `\n您的订阅内容由 内置 addresses/ADD* 参数变量提供\n`; - if (addresses.length > 0) 订阅器 += `ADD(TLS优选域名&IP): \n ${addresses.join('\n ')}\n`; - if (addressesnotls.length > 0) 订阅器 += `ADDNOTLS(noTLS优选域名&IP): \n ${addressesnotls.join('\n ')}\n`; - if (addressesapi.length > 0) 订阅器 += `ADDAPI(TLS优选域名&IP 的 API): \n ${addressesapi.join('\n ')}\n`; - if (addressesnotlsapi.length > 0) 订阅器 += `ADDNOTLSAPI(noTLS优选域名&IP 的 API): \n ${addressesnotlsapi.join('\n ')}\n`; - if (addressescsv.length > 0) 订阅器 += `ADDCSV(IPTest测速csv文件 限速 ${DLS} ): \n ${addressescsv.join('\n ')}\n`; + if (enableSocks) 订阅器 += `CFCDN(访问方式): Socks5
  ${newSocks5s.join('
  ')}
${socks5List}`; + else if (proxyIP && proxyIP != '') 订阅器 += `CFCDN(访问方式): ProxyIP
  ${proxyIPs.join('
  ')}
`; + else 订阅器 += `CFCDN(访问方式): 无法访问, 需要您设置 proxyIP/PROXYIP !!!
`; + let 判断是否绑定KV空间 = ''; + if (env.KV) 判断是否绑定KV空间 = ` 编辑优选列表`; + 订阅器 += `
您的订阅内容由 内置 addresses/ADD* 参数变量提供${判断是否绑定KV空间}
`; + if (addresses.length > 0) 订阅器 += `ADD(TLS优选域名&IP):
  ${addresses.join('
  ')}
`; + if (addressesnotls.length > 0) 订阅器 += `ADDNOTLS(noTLS优选域名&IP):
  ${addressesnotls.join('
  ')}
`; + if (addressesapi.length > 0) 订阅器 += `ADDAPI(TLS优选域名&IP 的 API):
  ${addressesapi.join('
  ')}
`; + if (addressesnotlsapi.length > 0) 订阅器 += `ADDNOTLSAPI(noTLS优选域名&IP 的 API):
  ${addressesnotlsapi.join('
  ')}
`; + if (addressescsv.length > 0) 订阅器 += `ADDCSV(IPTest测速csv文件 限速 ${DLS} ):
  ${addressescsv.join('
  ')}
`; } if (动态UUID && _url.pathname !== `/${动态UUID}`) 订阅器 = ''; - else 订阅器 += `\nSUBAPI(订阅转换后端): ${subProtocol}://${subConverter}\nSUBCONFIG(订阅转换配置文件): ${subConfig}`; - const 动态UUID信息 = (uuid != userID) ? `TOKEN: ${uuid}\nUUIDNow: ${userID}\nUUIDLow: ${userIDLow}\n${userIDTime}TIME(动态UUID有效时间): ${有效时间} 天\nUPTIME(动态UUID更新时间): ${更新时间} 时(北京时间)\n\n` : `${userIDTime}`; - return ` -################################################################ -Subscribe / sub 订阅地址, 支持 Base64、clash-meta、sing-box 订阅格式 ---------------------------------------------------------------- -快速自适应订阅地址: -https://${proxyhost}${hostName}/${uuid} -https://${proxyhost}${hostName}/${uuid}?sub + else 订阅器 += `
SUBAPI(订阅转换后端): ${subProtocol}://${subConverter}
SUBCONFIG(订阅转换配置文件): ${subConfig}`; + const 动态UUID信息 = (uuid != userID) ? `TOKEN: ${uuid}
UUIDNow: ${userID}
UUIDLow: ${userIDLow}
${userIDTime}TIME(动态UUID有效时间): ${有效时间} 天
UPTIME(动态UUID更新时间): ${更新时间} 时(北京时间)

` : `${userIDTime}`; + const 节点配置页 = ` + ################################################################
+ Subscribe / sub 订阅地址, 支持 Base64、clash-meta、sing-box 订阅格式
+ ---------------------------------------------------------------
+ 自适应订阅地址:
+ https://${proxyhost}${hostName}/${uuid}
+ https://${proxyhost}${hostName}/${uuid}?sub
+
+ Base64订阅地址:
+ https://${proxyhost}${hostName}/${uuid}?b64
+ https://${proxyhost}${hostName}/${uuid}?base64
+
+ clash订阅地址:
+ https://${proxyhost}${hostName}/${uuid}?clash
+
+ singbox订阅地址:
+ https://${proxyhost}${hostName}/${uuid}?sb
+ https://${proxyhost}${hostName}/${uuid}?singbox
-Base64订阅地址: -https://${proxyhost}${hostName}/${uuid}?b64 -https://${proxyhost}${hostName}/${uuid}?base64 - -clash订阅地址: -https://${proxyhost}${hostName}/${uuid}?clash - -singbox订阅地址: -https://${proxyhost}${hostName}/${uuid}?sb -https://${proxyhost}${hostName}/${uuid}?singbox ---------------------------------------------------------------- -################################################################ -${FileName} 配置信息 ---------------------------------------------------------------- -${动态UUID信息}HOST: ${hostName} -UUID: ${userID} -FKID: ${fakeUserID} -UA: ${UA} -${订阅器} ---------------------------------------------------------------- -################################################################ -v2ray ---------------------------------------------------------------- -${v2ray} ---------------------------------------------------------------- -################################################################ -clash-meta ---------------------------------------------------------------- -${clash} ---------------------------------------------------------------- -################################################################ -${decodeURIComponent(atob('dGVsZWdyYW0lMjAlRTQlQkElQTQlRTYlQjUlODElRTclQkUlQTQlMjAlRTYlOEElODAlRTYlOUMlQUYlRTUlQTQlQTclRTQlQkQlQUMlN0UlRTUlOUMlQTglRTclQkElQkYlRTUlOEYlOTElRTclODklOEMhCmh0dHBzJTNBJTJGJTJGdC5tZSUyRkNNTGl1c3NzcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZ2l0aHViJTIwJUU5JUExJUI5JUU3JTlCJUFFJUU1JTlDJUIwJUU1JTlEJTgwJTIwU3RhciFTdGFyIVN0YXIhISEKaHR0cHMlM0ElMkYlMkZnaXRodWIuY29tJTJGY21saXUlMkZlZGdldHVubmVsCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQolMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjM='))} -`; + + ---------------------------------------------------------------
+ ################################################################
+ ${FileName} 配置信息
+ ---------------------------------------------------------------
+ ${动态UUID信息}HOST: ${hostName}
+ UUID: ${userID}
+ FKID: ${fakeUserID}
+ UA: ${UA}
+ ${订阅器}
+ ---------------------------------------------------------------
+ ################################################################
+ v2ray
+ ---------------------------------------------------------------
+ ${v2ray}
+ ---------------------------------------------------------------
+ ################################################################
+ clash-meta
+ ---------------------------------------------------------------
+ ${clash}
+ ---------------------------------------------------------------
+ ################################################################
+ ${decodeURIComponent(atob('dGVsZWdyYW0lMjAlRTQlQkElQTQlRTYlQjUlODElRTclQkUlQTQlMjAlRTYlOEElODAlRTYlOUMlQUYlRTUlQTQlQTclRTQlQkQlQUMlN0UlRTUlOUMlQTglRTclQkElQkYlRTUlOEYlOTElRTclODklOEMhJTNDYnIlM0UKJTNDYSUyMGhyZWYlM0QlMjdodHRwcyUzQSUyRiUyRnQubWUlMkZDTUxpdXNzc3MlMjclM0VodHRwcyUzQSUyRiUyRnQubWUlMkZDTUxpdXNzc3MlM0MlMkZhJTNFJTNDYnIlM0UKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJTNDYnIlM0UKZ2l0aHViJTIwJUU5JUExJUI5JUU3JTlCJUFFJUU1JTlDJUIwJUU1JTlEJTgwJTIwU3RhciFTdGFyIVN0YXIhISElM0NiciUzRQolM0NhJTIwaHJlZiUzRCUyN2h0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmNtbGl1JTJGZWRnZXR1bm5lbCUyNyUzRWh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRmNtbGl1JTJGZWRnZXR1bm5lbCUzQyUyRmElM0UlM0NiciUzRQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0lM0NiciUzRQolMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjMlMjM='))} + `; + return 节点配置页; } else { if (typeof fetch != 'function') { return 'Error: fetch is not available in this environment.'; @@ -1749,6 +1771,7 @@ function 生成本地订阅(host,UUID,noTLS,newAddressesapi,newAddressescsv,newA let base64Response = responseBody; // 重新进行 Base64 编码 if(noTLS == 'true') base64Response += `\n${notlsresponseBody}`; + if (link.length > 0) base64Response += '\n' + link.join('\n'); return btoa(base64Response); } @@ -1832,4 +1855,165 @@ function 生成动态UUID(密钥) { const 到期时间字符串 = `到期时间(UTC): ${到期时间UTC.toISOString().slice(0, 19).replace('T', ' ')} (UTC+8): ${结束时间.toISOString().slice(0, 19).replace('T', ' ')}\n`; return Promise.all([当前UUIDPromise, 上一个UUIDPromise, 到期时间字符串]); +} + +async function KV(request, env) { + try { + // POST请求处理 + if (request.method === "POST") { + if (!env.KV) return new Response("未绑定KV空间", { status: 400 }); + try { + const content = await request.text(); + await env.KV.put('/ADD.txt', content); + return new Response("保存成功"); + } catch (error) { + console.error('保存KV时发生错误:', error); + return new Response("保存失败: " + error.message, { status: 500 }); + } + } + + // GET请求部分 + let content = ''; + let hasKV = !!env.KV; + + if (hasKV) { + try { + content = await env.KV.get('/ADD.txt') || ''; + } catch (error) { + console.error('读取KV时发生错误:', error); + content = '读取数据时发生错误: ' + error.message; + } + } + + const html = ` + + + + KV编辑器 + + + + + +
+ ${hasKV ? ` + +
+ + + +
+ ` : '

未绑定KV空间

'} +
+ + + + + `; + + return new Response(html, { + headers: { "Content-Type": "text/html;charset=utf-8" } + }); + } catch (error) { + console.error('处理请求时发生错误:', error); + return new Response("服务器错误: " + error.message, { + status: 500, + headers: { "Content-Type": "text/plain;charset=utf-8" } + }); + } } \ No newline at end of file