您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Enhanced CDN detection with accurate rules for major providers. Displays CDN provider, cache status, server info and POP locations. 增强版CDN检测,支持更多服务商,准确显示CDN提供商、缓存状态、服务器信息和节点位置。
当前为
// ==UserScript== // @name CDN & Server Info Displayer Enhanced (增强版CDN及服务器信息显示) // @namespace http://tampermonkey.net/ // @version 2025.06.11.05 enhanced // @description Enhanced CDN detection with accurate rules for major providers. Displays CDN provider, cache status, server info and POP locations. 增强版CDN检测,支持更多服务商,准确显示CDN提供商、缓存状态、服务器信息和节点位置。 // @author Claude (Enhanced by AI) // @license MIT // @match *://*/* // @grant GM_addStyle // @run-at document-end // ==/UserScript== (function() { 'use strict'; // --- 配置项 --- const config = { initialPosition: { bottom: '15px', right: '15px' }, panelBgColor: 'rgba(44, 62, 80, 0.95)', // 增加透明度 panelTextColor: '#ffffff', borderColor: '#3498db', opacity: '0.9', showDetailed: true, // 是否显示详细信息 animationDuration: '0.3s', // 过滤配置 minWindowSize: { width: 400, height: 300 }, // 最小窗口尺寸 excludePatterns: [ // 验证码相关 /captcha/i, /recaptcha/i, /hcaptcha/i, /turnstile/i, // 支付相关 /pay(pal|ment)/i, /checkout/i, /billing/i, // 登录(不可用)弹窗 /login/i, /signin/i, /auth/i, /oauth/i, // 广告相关 /ads/i, /advertisement/i, /doubleclick/i, // 社交媒体插件 /facebook\.com\/plugins/i, /twitter\.com\/widgets/i, // 其他小工具 /widget/i, /embed/i, /popup/i, /modal/i ] }; // --- CDN 服务商检测规则 (修正并增强) --- const cdnProviders = { 'Cloudflare': { headers: ['cf-ray', 'cf-cache-status', 'cf-request-id'], serverHeaders: ['cloudflare'], priority: 10, getInfo: (headers) => { const ray = headers.get('cf-ray'); const cacheStatus = headers.get('cf-cache-status'); const datacenter = ray ? ray.slice(-3).toUpperCase() : 'N/A'; return { provider: 'Cloudflare', cache: cacheStatus?.toUpperCase() || 'N/A', pop: datacenter, extra: headers.get('cf-request-id') ? 'Request ID available' : null }; } }, 'Alibaba Cloud CDN': { headers: ['ali-swift-global-savetime', 'eagleid', 'x-cache-remote', 'x-swift-cachetime'], serverHeaders: ['tengine', 'alicdn'], priority: 9, getInfo: (headers) => { // 阿里云CDN的正确检测规则 const cacheRemote = headers.get('x-cache-remote'); const swiftCache = headers.get('x-swift-cachetime'); const eagleId = headers.get('eagleid'); let cacheStatus = 'N/A'; if (cacheRemote) { cacheStatus = cacheRemote.includes('HIT') ? 'HIT' : 'MISS'; } else if (swiftCache) { cacheStatus = 'HIT'; } // 从EagleEye TraceId提取节点信息 let pop = 'N/A'; if (eagleId) { const popMatch = eagleId.match(/(\w{2,3})-/); pop = popMatch ? popMatch[1].toUpperCase() : 'N/A'; } return { provider: 'Alibaba Cloud CDN', cache: cacheStatus, pop: pop, extra: headers.get('ali-swift-global-savetime') ? 'Global acceleration' : null }; } }, 'Tencent Cloud CDN': { headers: ['x-cache-lookup', 'x-nws-log-uuid', 'x-cache-remote'], serverHeaders: ['nws', 'tencent'], priority: 9, getInfo: (headers) => { const cacheLookup = headers.get('x-cache-lookup'); const cacheRemote = headers.get('x-cache-remote'); const nwsLog = headers.get('x-nws-log-uuid'); let cacheStatus = 'N/A'; if (cacheLookup) { cacheStatus = cacheLookup.split(' ')[0].toUpperCase(); } else if (cacheRemote?.includes('HIT')) { cacheStatus = 'HIT'; } return { provider: 'Tencent Cloud CDN', cache: cacheStatus, pop: nwsLog ? 'Available' : 'N/A', extra: null }; } }, 'AWS CloudFront': { headers: ['x-amz-cf-pop', 'x-amz-cf-id', 'x-cache'], priority: 9, getInfo: (headers) => { const pop = headers.get('x-amz-cf-pop'); const cache = headers.get('x-cache'); return { provider: 'AWS CloudFront', cache: cache?.split(' from ')[0] || 'N/A', pop: pop || 'N/A', extra: headers.get('x-amz-cf-id') ? 'Request ID available' : null }; } }, 'QUIC.cloud': { headers: ['x-qc-cache', 'x-qc-pop', 'x-litespeed-cache'], serverHeaders: ['litespeed'], priority: 8, getInfo: (headers) => { const qcCache = headers.get('x-qc-cache'); const lsCache = headers.get('x-litespeed-cache'); const pop = headers.get('x-qc-pop'); let cacheStatus = qcCache || lsCache || 'N/A'; if (cacheStatus !== 'N/A') { cacheStatus = cacheStatus.toUpperCase(); } return { provider: 'QUIC.cloud', cache: cacheStatus, pop: pop?.toUpperCase() || 'N/A', extra: null }; } }, 'Fastly': { headers: ['x-served-by', 'x-cache', 'fastly-debug-digest'], priority: 8, getInfo: (headers) => { const servedBy = headers.get('x-served-by'); const cache = headers.get('x-cache'); return { provider: 'Fastly', cache: cache?.split(',')[0] || 'N/A', pop: servedBy?.split('-')[0] || 'N/A', extra: headers.get('fastly-debug-digest') ? 'Debug info available' : null }; } }, 'KeyCDN': { headers: ['x-edge-location', 'x-cache'], serverHeaders: ['keycdn'], priority: 7, getInfo: (headers) => ({ provider: 'KeyCDN', cache: headers.get('x-cache') || 'N/A', pop: headers.get('x-edge-location') || 'N/A', extra: null }) }, 'MaxCDN/StackPath': { headers: ['x-served-by', 'x-cache'], check: (headers) => { const servedBy = headers.get('x-served-by'); return servedBy && servedBy.includes('maxcdn'); }, priority: 7, getInfo: (headers) => ({ provider: 'MaxCDN/StackPath', cache: headers.get('x-cache') || 'N/A', pop: headers.get('x-served-by')?.split('.')[0] || 'N/A', extra: null }) }, 'Vercel Edge Network': { headers: ['x-vercel-id', 'x-vercel-cache'], priority: 8, getInfo: (headers) => { const vercelId = headers.get('x-vercel-id'); const cache = headers.get('x-vercel-cache'); let pop = 'N/A'; if (vercelId) { const parts = vercelId.split('::'); if (parts.length > 1) { pop = parts[1].split('-')[0].toUpperCase(); } } return { provider: 'Vercel Edge Network', cache: cache?.toUpperCase() || 'N/A', pop: pop, extra: null }; } }, 'BunnyCDN': { headers: ['cdn-cache', 'cdn-pullzone', 'cdn-requestid'], serverHeaders: ['bunnycdn'], priority: 7, getInfo: (headers) => ({ provider: 'BunnyCDN', cache: headers.get('cdn-cache')?.toUpperCase() || 'N/A', pop: headers.get('cdn-pullzone') || 'N/A', extra: headers.get('cdn-requestid') ? 'Request ID available' : null }) }, 'Akamai': { headers: ['x-akamai-transformed', 'x-check-cacheable', 'x-cache-key'], priority: 9, getInfo: (headers) => { const cache = headers.get('x-check-cacheable') || headers.get('x-cache'); return { provider: 'Akamai', cache: cache || 'N/A', pop: 'N/A', extra: headers.get('x-akamai-transformed') ? 'Content transformed' : null }; } }, 'Azure CDN': { headers: ['x-azure-ref', 'x-cache'], priority: 8, getInfo: (headers) => ({ provider: 'Azure CDN', cache: headers.get('x-cache') || 'N/A', pop: headers.get('x-azure-ref')?.split(':')[0] || 'N/A', extra: null }) }, 'Google Cloud CDN': { headers: ['x-goog-generation', 'x-goog-hash', 'x-cache'], serverHeaders: ['gws'], priority: 8, getInfo: (headers) => ({ provider: 'Google Cloud CDN', cache: headers.get('x-cache') || 'N/A', pop: 'N/A', extra: headers.get('x-goog-generation') ? 'Object versioning' : null }) }, 'Netlify': { headers: ['x-nf-request-id'], serverHeaders: ['netlify'], priority: 7, getInfo: (headers) => ({ provider: 'Netlify Edge', cache: 'N/A', pop: 'N/A', extra: 'Netlify Edge Network' }) }, 'jsDelivr': { headers: ['x-served-by'], check: (headers) => { const servedBy = headers.get('x-served-by'); return servedBy && servedBy.includes('jsdelivr'); }, priority: 6, getInfo: (headers) => ({ provider: 'jsDelivr CDN', cache: 'N/A', pop: headers.get('x-served-by')?.split('-')[0] || 'N/A', extra: 'Open Source CDN' }) } }; /** * 从headers中解析CDN或服务器信息 */ function parseInfo(headers) { const lowerCaseHeaders = new Map(); for (const [key, value] of headers.entries()) { lowerCaseHeaders.set(key.toLowerCase(), value); } let detectedProviders = []; // 检测所有匹配的CDN提供商 for (const [cdnName, cdn] of Object.entries(cdnProviders)) { let isMatch = false; // 检查特定的头部字段 if (cdn.headers?.some(header => lowerCaseHeaders.has(header.toLowerCase()))) { isMatch = true; } // 检查服务器头部 if (cdn.serverHeaders) { const serverHeader = lowerCaseHeaders.get('server') || ''; if (cdn.serverHeaders.some(server => serverHeader.toLowerCase().includes(server.toLowerCase()))) { isMatch = true; } } // 自定义检查函数 if (cdn.check && cdn.check(lowerCaseHeaders)) { isMatch = true; } if (isMatch) { const info = cdn.getInfo(lowerCaseHeaders); detectedProviders.push({ ...info, priority: cdn.priority || 5 }); } } // 如果检测到多个CDN,选择优先级最高的 if (detectedProviders.length > 0) { detectedProviders.sort((a, b) => b.priority - a.priority); return detectedProviders[0]; } // 如果没有匹配到已知CDN,尝试显示服务器信息 const server = lowerCaseHeaders.get('server'); const xCache = lowerCaseHeaders.get('x-cache'); const via = lowerCaseHeaders.get('via'); if (server || xCache || via) { return { provider: server || 'Unknown Server', cache: xCache?.split(' ')[0] || 'N/A', pop: via ? 'Proxy detected' : 'N/A', extra: via ? `Via: ${via}` : null }; } return { provider: 'Direct Connection', cache: 'N/A', pop: 'N/A', extra: 'No CDN detected' }; } /** * 创建样式 */ function addStyles() { GM_addStyle(` #cdn-info-panel-enhanced { position: fixed; z-index: 99999; padding: 12px 16px; border-radius: 12px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-size: 13px; color: ${config.panelTextColor}; background: ${config.panelBgColor}; backdrop-filter: blur(10px); border: 1px solid ${config.borderColor}; box-shadow: 0 8px 32px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.1); cursor: move; user-select: none; transition: opacity ${config.animationDuration}, transform ${config.animationDuration}; opacity: ${config.opacity}; transform: scale(1); min-width: 200px; } #cdn-info-panel-enhanced:hover { opacity: 1; transform: scale(1.02); } #cdn-info-panel-enhanced .panel-header { font-weight: 600; font-size: 14px; margin-bottom: 8px; color: ${config.borderColor}; text-align: center; border-bottom: 1px solid rgba(52, 152, 219, 0.3); padding-bottom: 6px; } #cdn-info-panel-enhanced .info-line { display: flex; justify-content: space-between; align-items: center; margin: 6px 0; padding: 2px 0; } #cdn-info-panel-enhanced .info-label { font-weight: 500; color: #a9cce3; font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; } #cdn-info-panel-enhanced .info-value { font-weight: 600; color: #ffffff; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: right; } #cdn-info-panel-enhanced .extra-info { font-size: 11px; color: #95a5a6; font-style: italic; text-align: center; margin-top: 8px; padding-top: 6px; border-top: 1px solid rgba(149, 165, 166, 0.2); } #cdn-info-panel-enhanced .cache-hit { color: #2ecc71 !important; } #cdn-info-panel-enhanced .cache-miss { color: #e74c3c !important; } #cdn-info-panel-enhanced .close-btn { position: absolute; top: -8px; right: -8px; width: 20px; height: 20px; border-radius: 50%; background: #e74c3c; color: white; border: none; cursor: pointer; font-size: 12px; display: none; align-items: center; justify-content: center; transition: all 0.2s; } #cdn-info-panel-enhanced:hover .close-btn { display: flex; } #cdn-info-panel-enhanced .close-btn:hover { background: #c0392b; transform: scale(1.1); } `); } /** * 创建并显示信息面板 */ function createDisplayPanel(info) { if (!info || document.getElementById('cdn-info-panel-enhanced')) return; addStyles(); const panel = document.createElement('div'); panel.id = 'cdn-info-panel-enhanced'; // 根据缓存状态添加样式类 let cacheClass = ''; if (info.cache.toLowerCase().includes('hit')) { cacheClass = 'cache-hit'; } else if (info.cache.toLowerCase().includes('miss')) { cacheClass = 'cache-miss'; } const providerLabel = info.provider.includes('CDN') || info.provider.includes('Cloud') || info.provider.includes('Edge') ? 'CDN' : 'Server'; panel.innerHTML = ` <button class="close-btn" onclick="this.parentElement.remove()">×</button> <div class="panel-header">CDN Detector</div> <div class="info-line"> <span class="info-label">${providerLabel}</span> <span class="info-value" title="${info.provider}">${info.provider}</span> </div> <div class="info-line"> <span class="info-label">Cache</span> <span class="info-value ${cacheClass}">${info.cache}</span> </div> <div class="info-line"> <span class="info-label">POP</span> <span class="info-value">${info.pop}</span> </div> ${info.extra ? `<div class="extra-info">${info.extra}</div>` : ''} `; // 设置初始位置 Object.assign(panel.style, config.initialPosition); document.body.appendChild(panel); // 使面板可拖拽 makeDraggable(panel); // 添加入场动画 requestAnimationFrame(() => { panel.style.opacity = config.opacity; }); } /** * 使元素可拖拽 */ function makeDraggable(element) { let isDragging = false; let startX = 0, startY = 0; let elementX = 0, elementY = 0; element.addEventListener('mousedown', dragStart, false); document.addEventListener('mousemove', drag, false); document.addEventListener('mouseup', dragEnd, false); function dragStart(e) { if (e.target.classList.contains('close-btn')) return; e.preventDefault(); isDragging = true; // 记录鼠标起始位置 startX = e.clientX; startY = e.clientY; // 获取元素当前位置 const rect = element.getBoundingClientRect(); elementX = rect.left; elementY = rect.top; // 移除过渡效果,确保拖拽流畅 element.style.transition = 'none'; // 添加拖拽时的视觉反馈 element.style.opacity = '1'; element.style.transform = 'scale(1.05)'; } function drag(e) { if (!isDragging) return; e.preventDefault(); // 计算鼠标移动的距离 const deltaX = e.clientX - startX; const deltaY = e.clientY - startY; // 计算元素新位置 const newX = elementX + deltaX; const newY = elementY + deltaY; // 边界检测,防止拖出屏幕 const maxX = window.innerWidth - element.offsetWidth; const maxY = window.innerHeight - element.offsetHeight; const finalX = Math.max(0, Math.min(newX, maxX)); const finalY = Math.max(0, Math.min(newY, maxY)); // 更新元素位置 element.style.position = 'fixed'; element.style.left = finalX + 'px'; element.style.top = finalY + 'px'; element.style.right = 'auto'; element.style.bottom = 'auto'; element.style.transform = 'scale(1.05)'; } function dragEnd() { if (!isDragging) return; isDragging = false; // 恢复过渡效果和正常状态 element.style.transition = `opacity ${config.animationDuration}, transform ${config.animationDuration}`; element.style.transform = 'scale(1)'; element.style.opacity = config.opacity; } } /** * [NEW] 检查是否应该显示CDN检测面板 */ function shouldShowPanel() { // 1. 检查是否在iframe中 if (window !== window.top) { console.log('[CDN Detector] Running in iframe, checking if should display...'); // 获取iframe尺寸 const frameWidth = window.innerWidth; const frameHeight = window.innerHeight; // iframe太小则不显示 if (frameWidth < config.minWindowSize.width || frameHeight < config.minWindowSize.height) { console.log(`[CDN Detector] Iframe too small (${frameWidth}x${frameHeight}), skipping display`); return false; } // 检查iframe的URL是否匹配排除模式 const currentUrl = window.location.href.toLowerCase(); for (const pattern of config.excludePatterns) { if (pattern.test(currentUrl)) { console.log(`[CDN Detector] URL matches exclude pattern: ${pattern}, skipping display`); return false; } } } // 2. 检查当前页面URL (对主窗口和iframe都适用) const currentUrl = window.location.href.toLowerCase(); for (const pattern of config.excludePatterns) { if (pattern.test(currentUrl)) { console.log(`[CDN Detector] Current URL matches exclude pattern: ${pattern}, skipping display`); return false; } } // 3. 检查页面标题 const pageTitle = document.title.toLowerCase(); const titleExcludePatterns = [ /captcha/i, /verify/i, /challenge/i, /security check/i, /human verification/i, /robot check/i ]; for (const pattern of titleExcludePatterns) { if (pattern.test(pageTitle)) { console.log(`[CDN Detector] Page title matches exclude pattern: ${pattern}, skipping display`); return false; } } // 4. 检查常见的验证码容器元素 const captchaSelectors = [ '[id*="captcha"]', '[class*="captcha"]', '[id*="recaptcha"]', '[class*="recaptcha"]', '[id*="hcaptcha"]', '[class*="hcaptcha"]', '[class*="cf-turnstile"]', '[id*="turnstile"]' ]; for (const selector of captchaSelectors) { if (document.querySelector(selector)) { console.log(`[CDN Detector] Found captcha element: ${selector}, skipping display`); return false; } } // 5. 检查特殊的域名 const hostname = window.location.hostname.toLowerCase(); const excludeDomains = [ 'accounts.google.com', 'login.microsoftonline.com', 'auth0.com', 'okta.com', 'captcha.com', 'recaptcha.net', 'hcaptcha.com', 'challenges.cloudflare.com' ]; for (const domain of excludeDomains) { if (hostname.includes(domain)) { console.log(`[CDN Detector] Excluded domain detected: ${domain}, skipping display`); return false; } } console.log('[CDN Detector] All checks passed, panel will be displayed.'); return true; } async function main() { // 等待页面完全加载 if (document.readyState !== "complete") { return new Promise(resolve => { window.addEventListener("load", () => { main().then(resolve); }); }); } // [MODIFIED] 在执行任何操作前,先检查是否应该显示面板 if (!shouldShowPanel()) { return; } try { console.log('[CDN Detector] Starting detection...'); // 尝试获取当前页面的响应头 const response = await fetch(window.location.href, { method: 'HEAD', // 使用HEAD请求减少数据传输 cache: 'no-cache', redirect: 'follow' }); const info = parseInfo(response.headers); console.log('[CDN Detector] Detection result:', info); createDisplayPanel(info); } catch (error) { console.warn('[CDN Detector] Failed to fetch headers:', error.message); // 降级处理:显示基于已知信息的检测结果 createDisplayPanel({ provider: 'Detection Limited', cache: 'N/A', pop: 'N/A', extra: 'CORS policy blocking header access' }); } } // 启动脚本 main().catch(error => { console.error('[CDN Detector] Initialization failed:', error); }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址