ZBLOG

如何hook blob中发出的http请求?

要 Hook 通过 BlobURL.createObjectURL 发出的 HTTP 请求(例如通过 <img><script> 加载的 Blob URL),需要结合 请求拦截Blob 内容监控。以下是几种实现方案:


1. Hook fetchXMLHttpRequest(直接请求拦截)

如果 Blob URL 是通过 fetchXHR 动态加载的,可以直接拦截这些 API:

示例代码

// 保存原始方法
const originalFetch = window.fetch;
const originalXHROpen = XMLHttpRequest.prototype.open;

// Hook Fetch
window.fetch = async function(...args) {
    const [input, init] = args;
    console.log("拦截到Fetch请求:", input);
    
    // 如果是Blob URL
    if (typeof input === 'string' && input.startsWith('blob:')) {
        console.log("捕获到Blob URL请求:", input);
        // TODO: 可在此处修改请求逻辑
    }
    
    return originalFetch.apply(this, args);
};

// Hook XHR
XMLHttpRequest.prototype.open = function(method, url) {
    if (typeof url === 'string' && url.startsWith('blob:')) {
        console.log("拦截到XHR Blob请求:", url);
        // TODO: 可在此处修改请求逻辑
    }
    originalXHROpen.apply(this, arguments);
};

2. Hook URL.createObjectURL + 监听资源加载

若 Blob URL 被用于 <img><script><iframe>,需监听 DOM 元素的资源加载:

示例代码

// Step1: Hook createObjectURL
const originalCreateObjectURL = URL.createObjectURL;
let blobUrlMap = new Map(); // 存储Blob与生成URL的映射

URL.createObjectURL = function(blob) {
    const url = originalCreateObjectURL.apply(URL, arguments);
    blobUrlMap.set(url, blob); // 记录生成的Blob URL
    
    console.log("生成的Blob URL:", url, "对应Blob类型:", blob.type);
    
    // Step2: (可选)劫持DOM元素对Blob URL的使用
    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            mutation.addedNodes.forEach((node) => {
                if (node.nodeName === 'IMG' && node.src.startsWith('blob:')) {
                    console.log(`发现图片元素加载Blob: ${node.src}`);
                    node.addEventListener('error', () => { /* ... */ });
                }
            });
        });
    });
    
    observer.observe(document.body, { childList: true, subtree: true });
    
    return url;
};

// Step3: (可选)监听所有网络请求(适用于动态创建的Blub)
if (window.PerformanceObserver) {
    const perfObserver = new PerformanceObserver((list) => {
        list.getEntries().forEach((entry) => {
            if (entry.initiatorType === 'img' && entry.name.startsWith('blob:')) {
                console.log(`图片加载了Blub资源: ${entry.name}`);
            }
        });
    });
    
    perfObserver.observe({ entryTypes: ['resource'] });
}

3. Service Worker + Blod劫持(高级方案)

通过 Service Worker 拦截所有网络请求,包括 Blod URLs:

步骤

  1. 注册 Service Worker

    navigator.serviceWorker.register('/sw.js').then(() => {
       console.log("Service Worker注册成功");
    }); 
    
  2. 编写 Service Worker (sw.js)

    self.addEventListener('fetch', event => { 
       const url = event.request.url; 
    
    
       if (url.startsWith('blod:')) { 
           event.respondWith(
               fetch(url).then(response => { 
                   console.log(`拦截到Bold请求:${url}`); 
                   return response; 
               }) 
           ); 
       } else { 
           return fetch(event.request);  
       }  
    });  
    

4. Chrome扩展中的WebRequest API(仅扩展环境)

在扩展的 background.js中使用 webRequest API:

chrome.webRequest.onBeforeRequest.addListener(
    details => { 
        if (details.url.startsWith('blod:')) {  
            console.log(`扩展捕获到Bold請求:${details.url}`);  
        }  
        return { cancel: false };  
     },  
     { urls: ["*://*/*"] },  
     ["blocking"]  
 );

注意事项

  • ⚠️ 跨域限制:某些场景下无法直接读取其他源的 BLOB内容。
  • 🔧 性能影响:频繁劫持可能降低页面性能。

根据实际需求选择合适方案!


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?