CDN & Server Info Displayer Enhanced (增强版CDN及服务器信息显示)

Enhanced CDN detection with accurate rules for major providers. Displays CDN provider, cache status, server info and POP locations. 增强版CDN检测,支持更多服务商,准确显示CDN提供商、缓存状态、服务器信息和节点位置。

当前为 2025-06-10 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         CDN & Server Info Displayer Enhanced (增强版CDN及服务器信息显示)
// @namespace    http://tampermonkey.net/
// @version      2025.06.11.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;
        }
    }

    /**
     * 检查是否应该显示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;
                }
            }

            // 检查父页面信息(如果可访问)
            try {
                const parentUrl = window.parent.location.href.toLowerCase();
                for (const pattern of config.excludePatterns) {
                    if (pattern.test(parentUrl)) {
                        console.log(`[CDN Detector] Parent URL matches exclude pattern: ${pattern}, skipping display`);
                        return false;
                    }
                }
            } catch (e) {
                // 跨域限制,无法访问父页面信息,这很常见
                console.log('[CDN Detector] Cannot access parent frame info (CORS), continuing...');
            }
        }

        // 2. 检查当前页面URL
        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. 检查窗口尺寸(对于主窗口)
        if (window === window.top) {
            const windowWidth = window.innerWidth;
            const windowHeight = window.innerHeight;

            if (windowWidth < config.minWindowSize.width || windowHeight < config.minWindowSize.height) {
                console.log(`[CDN Detector] Main window too small (${windowWidth}x${windowHeight}), skipping display`);
                return false;
            }
        }

        // 6. 检查特殊的域名
        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);
                });
            });
        }

        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);
    });

})();