ZBLOG

通过 Blob 生成的JS脚本运行在独立的上下文中,在HTML页面中HOOK的fetch对它无效,要怎么操作才能让blob fetch函数进入HOOK代码

要让通过 Blob 生成的 JS 脚本中的 fetch 请求也能被 HTML 页面中已有的 Hook 代码捕获,可以通过以下几种方法实现:


方法 1:重写全局 fetch(推荐)

在 Blob 脚本执行前,确保全局 fetch 已被替换。由于 Blob 脚本默认继承当前页面的全局对象(包括 window.fetch),只需在页面主线程中提前劫持原生 fetch

// 保存原生 fetch
const nativeFetch = window.fetch;

// 替换全局 fetch
window.fetch = function(...args) {
    console.log('Hook fetch:', args);
    // 在这里添加你的拦截逻辑
    return nativeFetch.apply(this, args);
};

// 生成并运行 Blob 脚本
const blob = new Blob([`
    fetch('https://api.example.com').then(response => console.log(response));
`], { type: 'application/javascript' });
const blobUrl = URL.createObjectURL(blob);
const script = document.createElement('script');
script.src = blobUrl;
document.body.appendChild(script);

关键点

  • Blob 脚本共享父页面的全局作用域,因此直接覆盖 window.fetch 即可生效。

方法 2:动态注入 Hook 代码到 Blob

如果无法提前劫持全局对象,可以在生成 Blob 时直接将 Hook 逻辑插入到脚本中:

const hookCode = `
    const nativeFetch = window.fetch;
    window.fetch = function(...args) {
        console.log('Blob fetch hooked:', args);
        return nativeFetch.apply(this, args);
    };
`;

const userCode = `
    fetch('https://api.example.com').then(response => console.log(response));
`;

// 合并 Hook 代码和用户代码
const blob = new Blob([hookCode + userCode], { type: 'application/javascript' });
const blobUrl = URL.createObjectURL(blob);
const script = document.createElement('script');
script.src = blobUrl;
document.body.appendChild(script);

方法3:使用代理拦截动态脚本

通过 MutationObserver监听 DOM 变化,在 Blob Script加载前强制注入 Hook:

// Hook逻辑
function injectHook() {
    const nativeFetch = window.fetch;
    window.fetch = function(...args) {
        console.log('Proxy fetch hooked:', args);
        return nativeFetch.apply(this, args);
    };
}

// 监听动态脚本加载
const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
        if (mutation.addedNodes.length) {
            mutation.addedNodes.forEach((node) => {
                if (node.tagName === 'SCRIPT' && node.src.startsWith('blob:')) {
                    injectHook();
                }
            });
        }
    });
});

observer.observe(document.body, { childList: true });

// 生成Blob脚本(同方法1)

注意事项

  1. 作用域隔离问题

    • Blob脚本默认共享父页面的全局对象,但某些框架(如沙箱环境)可能隔离了作用域。此时需通过 postMessage通信或直接修改沙箱配置。
  2. Service Worker拦截

    • Service Worker可以拦截所有网络请求,即使来自Blob的请求也会被捕获:
      
      navigator.serviceWorker.register('/sw.js').then(() => {
       // Service Worker会接管fetch
      });
      
  3. CSP限制

    • Content Security Policy可能会阻止Blob执行,需检查HTTP头部的CSP规则。

总结

  • 优先方案:直接覆盖 window.fetch(方法1)。
  • 复杂场景:组合使用动态注入(方法2)或代理监听(方法3)。
  • 终极方案:Service Worker无差别拦截所有请求。

根据实际需求选择最适合的方式即可。


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?