diff --git a/_worker.js b/_worker.js index deda71c..779b1cb 100644 --- a/_worker.js +++ b/_worker.js @@ -10,6 +10,8 @@ let SUBUpdateTime = 6; //自定义订阅更新时间,单位小时 let total = 99;//TB let timestamp = 4102329600000;//2099-12-31 +let cacheTTL = 24 ;//小时,缓存时长 + //节点链接 + 订阅链接 let MainData = ` vless://b7a392e2-4ef0-4496-90bc-1c37bb234904@cf.090227.xyz:443?encryption=none&security=tls&sni=edgetunnel-2z2.pages.dev&fp=random&type=ws&host=edgetunnel-2z2.pages.dev&path=%2F%3Fed%3D2048#%E5%8A%A0%E5%85%A5%E6%88%91%E7%9A%84%E9%A2%91%E9%81%93t.me%2FCMLiussss%E8%A7%A3%E9%94%81%E6%9B%B4%E5%A4%9A%E4%BC%98%E9%80%89%E8%8A%82%E7%82%B9 @@ -98,13 +100,9 @@ export default { let 订阅转换URL = `${url.origin}/${await MD5MD5(fakeToken)}?token=${fakeToken}`; //console.log(订阅转换URL); let req_data = MainData; - // 创建一个AbortController对象,用于控制fetch请求的取消 - const controller = new AbortController(); - - const timeout = setTimeout(() => { - controller.abort(); // 取消所有请求 - }, 2000); // 2秒后触发 - + + // 初始化缓存 + const cache = caches.default; let 追加UA = 'v2rayn'; if (url.searchParams.has('clash')){ @@ -116,48 +114,73 @@ export default { } try { - const responses = await Promise.allSettled(urls.map(url => - fetch(url, { - method: 'get', - headers: { - 'Accept': 'text/html,application/xhtml+xml,application/xml;', - 'User-Agent': `${追加UA} cmliu/CF-Workers-SUB ${userAgentHeader}` - }, - signal: controller.signal // 将AbortController的信号量添加到fetch请求中,以便于需要时可以取消请求 - }).then(response => { + const responses = await Promise.all(urls.map(async url => { + const cacheKey = new Request(url); + + try { + // 设置2秒超时 + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 2000); + + const response = await fetch(url, { + method: 'get', + headers: { + 'Accept': 'text/html,application/xhtml+xml,application/xml;', + 'User-Agent': `${追加UA} cmliu/CF-Workers-SUB ${userAgentHeader}` + }, + signal: controller.signal + }); + + clearTimeout(timeoutId); + if (response.ok) { - return response.text().then(content => { - // 这里可以顺便做内容检查 - if (content.includes('dns') && content.includes('proxies') && content.includes('proxy-groups')) { - //console.log("clashsub: " + url); - 订阅转换URL += "|" + url; - } else if (content.includes('dns') && content.includes('outbounds') && content.includes('inbounds')){ - //console.log("singboxsub: " + url); - 订阅转换URL += "|" + url; - } else { - //console.log("未识别" + url); - return content; // 保证链式调用中的下一个then可以接收到文本内容 + const content = await response.text(); + + // 请求成功,写入缓存,设置24小时的缓存时间 + const cacheResponse = new Response(content, { + headers: { + ...response.headers, + 'Cache-Control': `public, max-age=${cacheTTL * 60 * 60}` } - //console.log(content); }); + await cache.put(cacheKey, cacheResponse); + console.log(`更新缓存 ${url}:\n${content.slice(0, 10)}...`); + if (content.includes('dns') && content.includes('proxies') && content.includes('proxy-groups')) { + // Clash 配置 + 订阅转换URL += "|" + url; + return ""; // 返回空字符串,因为这种情况下我们不需要内容 + } else if (content.includes('dns') && content.includes('outbounds') && content.includes('inbounds')){ + // Singbox 配置 + 订阅转换URL += "|" + url; + return ""; // 返回空字符串,因为这种情况下我们不需要内容 + } else { + return content; + } } else { - return ""; // 如果response.ok为false,返回空字符串 + throw new Error('请求失败'); } - }) - )); + } catch (error) { + // 请求失败或超时,尝试从缓存读取 + const cachedResponse = await cache.match(cacheKey); + if (cachedResponse) { + const cachedContent = await cachedResponse.text(); + console.log(`使用缓存内容 ${url}:\n${cachedContent.slice(0, 10)}...`); + return cachedResponse.text(); + } else { + console.log(`无缓存可用 ${url}`); + return ""; // 缓存中也没有,返回空字符串 + } + } + })); for (const response of responses) { - if (response.status === 'fulfilled' && response.value) { - const content = response.value; - req_data += base64Decode(content) + '\n'; + if (response) { + req_data += base64Decode(response) + '\n'; } } } catch (error) { - //console.error(error); - } finally { - // 无论成功或失败,最后都清除设置的超时定时器 - clearTimeout(timeout); + console.error('处理 URL 时发生错误:', error); } //修复中文错误 @@ -168,7 +191,7 @@ export default { //去重 const uniqueLines = new Set(text.split('\n')); const result = [...uniqueLines].join('\n'); - console.log(result); + //console.log(result); const base64Data = btoa(result); @@ -187,7 +210,7 @@ export default { } else if (订阅格式 == 'surge'){ subconverterUrl = `${subProtocol}://${subconverter}/sub?target=surge&url=${encodeURIComponent(订阅转换URL)}&insert=false&config=${encodeURIComponent(subconfig)}&emoji=true&list=false&tfo=false&scv=true&fdn=false&sort=false&new_name=true`; } - console.log(订阅转换URL); + //console.log(订阅转换URL); try { const subconverterResponse = await fetch(subconverterUrl);