ZBLOG

如何hook setAttributeNode,修改元素的URL

要 Hook setAttributeNode 并修改元素的 URL(例如 <a> 标签的 href<img>src),可以通过 JavaScript 原型劫持Proxy API浏览器扩展实现。以下是具体方案:


方法1:直接劫持 Element.prototype.setAttributeNode

覆盖原生方法,在调用时拦截并修改目标属性:

const originalSetAttributeNode = Element.prototype.setAttributeNode;

Element.prototype.setAttributeNode = function(attr) {
    // 仅处理特定属性(如 href/src)
    if (attr.name === 'href' || attr.name === 'src') {
        const newUrl = modifyUrl(attr.value); // 自定义URL修改逻辑
        attr.value = newUrl;
    }
    return originalSetAttributeNode.call(this, attr);
};

// 示例:追加时间戳到URL
function modifyUrl(url) {
    return url.includes('?') ? `${url}&t=${Date.now()}` : `${url}?t=${Date.now()}`;
}

// 测试用例
const link = document.createElement('a');
const hrefAttr = document.createAttribute('href');
hrefAttr.value = 'https://example.com';
link.setAttributeNode(hrefAttr);
console.log(link.getAttribute('href')); // 输出修改后的URL

方法2:使用 Proxy 监听 DOM 操作

通过 Proxy 动态拦截属性设置行为:

const elementProxyHandler = {
    set(target, prop, value) {
        if (prop === 'setAttributeNode' && value instanceof Attr) {
            if (value.name === 'href' || value.name === 'src') {
                value.value = modifyUrl(value.value); // 同上修改逻辑
            }
        }
        return Reflect.set(...arguments);
    }
};

// Wrap a specific element with Proxy
const element = document.querySelector('a');
const proxiedElement = new Proxy(element, elementProxyHandler);

// 后续操作均会被拦截
proxiedElement.setAttributeNode(hrefAttr);

方法3:MutationObserver(间接监听)

适用于无法直接劫持的场景(如第三方脚本):

const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
        if (mutation.type === 'attributes' && 
            (mutation.attributeName === 'href' || mutation.attributeName === 'src')) {
            const newUrl = modifyUrl(mutation.target.getAttribute(mutation.attributeName));
            mutation.target.setAttribute(mutation.attributeName, newUrl);
        }
    });
});

observer.observe(document.body, { 
    attributes: true,
    subtree: true,
    attributeFilter: ['href', 'src']
});

注意事项

  1. 兼容性

    • Proxy 无法覆盖已存在的 DOM 方法,需提前初始化。
    • MutationObserver 无法阻止原始调用,只能事后修正。
  2. 性能影响

    • Hook DOM API可能引发性能问题,建议仅在必要时使用。
  3. 安全限制

    • Chrome Extensions需在 content_script中执行,且受CSP策略限制。
  4. 更彻底的方案

    • C++级别Hook(如浏览器插件开发):通过修改Chromium/WebKit源码实现底层拦截。

如果需要针对特定场景优化或有其他需求,可以进一步讨论!


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?