ZBLOG

// 创建style元素 const style = document.createElement('style'); // 设置CSS内容 style.textContent = ` .dynamic-class { color: red; font-size: 16px; background-color: #f0f0f0; } #dynamic-id { border: 1px sol...

可以通过 Hook Node.prototype.appendChild 来实现拦截并修改 CSS 中的 URL。以下是完整的实现方案:

// 保存原始 appendChild 方法
const originalAppendChild = Node.prototype.appendChild;

// Hook appendChild 方法
Node.prototype.appendChild = function(node) {
    // 检查是否是 style 元素或包含样式表的内容
    if (node.nodeType === Node.ELEMENT_NODE) {
        if (node.tagName === 'STYLE') {
            // 如果是 style 元素,处理其文本内容
            processStyleContent(node);
        } else if (node.sheet && node.sheet.cssRules) {
            // 如果是 link 元素或者已经有样式表的元素
            processStyleSheet(node.sheet);
        }
    } else if (node.nodeType === Node.TEXT_NODE && 
               this.nodeType === Node.ELEMENT_NODE && 
               this.tagName === 'STYLE') {
        // 如果是添加到 style 元素的文本节点
        processStyleTextContent(node);
    }

    // 调用原始方法
    return originalAppendChild.call(this, node);
};

// 处理 style 元素的文本内容
function processStyleContent(styleElement) {
    if (styleElement.textContent) {
        styleElement.textContent = replaceCSSUrls(styleElement.textContent);
    }
    
    // 监听后续的内容变化
    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            if (mutation.type === 'characterData' || 
                (mutation.type === 'childList' && mutation.addedNodes.length > 0)) {
                styleElement.textContent = replaceCSSUrls(styleElement.textContent);
            }
        });
    });
    
    observer.observe(styleElement, {
        characterData: true,
        childList: true,
        subtree: true
    });
}

// 处理文本节点的内容(当文本被添加到 style 元素时)
function processStyleTextContent(textNode) {
    textNode.textContent = replaceCSSUrls(textNode.textContent);
}

// 处理现有的样式表
function processStyleSheet(sheet) {
    try {
        const rules = sheet.cssRules || sheet.rules;
        for (let i = 0; i < rules.length; i++) {
            const rule = rules[i];
            if (rule.style && rule.style.cssText) {
                rule.style.cssText = replaceCSSUrls(rule.style.cssText);
            }
            
            // 递归处理媒体查询等嵌套规则
            if (rule.cssRules) {
                processStyleSheet(rule);
            }
        }
    } catch (e) {
        // 可能会因为跨域限制而无法访问某些规则
        console.warn('无法访问样式表规则:', e);
    }
}

// CSS URL 替换函数 - 这是核心的 URL修改逻辑
function replaceCSSUrls(cssText) {
    return cssText.replace(/url\s*\(\s*['"]?(.*?)['"]?\s*\)/gi, (match, url) => {
        // 在这里修改 URL,例如添加前缀、域名替换等
        
        
         console.log('捕获到 CSS URL:', url);   
        
         
         let newUrl=url;
         
         /*  示例修改:
         1.  添加 CDN  前缀*/
         newUrl='https://cdn.example.com'+url;
         
         /*2.  替换域名*/
         newUrl=url.replace('old-domain.com','new-domain.com');
         
         /*3.  添加时间戳参数(避免缓存)*/
         newUrl=url+(url.includes('?')?'&':'?')+'t='+Date.now();
         
         
        
       return `url("${newUrl}")`;
       
       
     });
}

//  使用示例:创建并测试 Hook 
const style=document.createElement('style');
style.textContent=`
 .bg-image{
      background-image: url('/images/bg.jpg');
 }
 .icon{
      background-image: url("data:image/svg+xml,...");
 }
 @font-face{
      font-family:'CustomFont';
      src: url('/fonts/font.woff2') format('woff2');
 }
`;

document.head.appendChild(style); //  这会触发我们的 Hook

console.log('Hook已安装,开始监控 CSS URL');

这个 Hook 的主要特性:

  1. 全面覆盖:拦截所有 appendChild 调用,检测是否为样式相关操作

  2. 多层处理

    • Style元素的文本内容
    • Link元素引入的样式表
    • Text节点直接添加到 Style元素
  3. 动态监控:使用 MutationObserver监听 Style元素内容的后续变化

  4. 安全处理:对可能因跨域限制无法访问的规则进行错误处理

  5. 灵活替换:在 replaceCSSUrls函数中可以实现各种URL重写逻辑

关键点说明:

  • 正则表达式 /url\s*\(\s*['"]?(.*?)['"]?\s*\)/gi用于匹配 CSS中的各种URL写法
  • 替换策略可以根据需求定制(CDN化、域名切换、缓存破坏等)
  • data URL也会被匹配但通常不需要修改,可以在替换函数中添加过滤逻辑

可以根据具体需求调整 replaceCSSUrls函数中的URL转换逻辑。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=24403

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?