ZBLOG

如何hook获取到xhr和fetch并且拿到服务器返回的响应头字段信息

Hook XHR 和 Fetch 获取响应头信息

要 hook XMLHttpRequest (XHR) 和 Fetch API 并获取服务器返回的响应头字段信息,你可以使用以下几种方法:

1. Hook XMLHttpRequest (XHR)

// 保存原始的 open 和 send 方法
const originalOpen = XMLHttpRequest.prototype.open;
const originalSend = XMLHttpRequest.prototype.send;

XMLHttpRequest.prototype.open = function(method, url) {
    this._url = url;
    return originalOpen.apply(this, arguments);
};

XMLHttpRequest.prototype.send = function(body) {
    const xhr = this;
    
    // Hook onreadystatechange
    const originalOnReadyStateChange = xhr.onreadystatechange;
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) { // DONE
            console.log('XHR Response Headers:', getAllResponseHeaders(xhr));
            console.log('URL:', xhr._url);
            console.log('Status:', xhr.status);
        }
        
        if (originalOnReadyStateChange) {
            originalOnReadyStateChange.apply(xhr, arguments);
        }
    };
    
    // Hook addEventListener for 'load' event
    const loadListener = function() {
        console.log('XHR Response Headers via EventListener:', getAllResponseHeaders(xhr));
    };
    xhr.addEventListener('load', loadListener);
    
    return originalSend.apply(xhr, arguments);
};

function getAllResponseHeaders(xhr) {
    const headersString = xhr.getAllResponseHeaders();
    const headersArray = headersString.trim().split(/[\r\n]+/);
    
    const headers = {};
    headersArray.forEach(line => {
        const parts = line.split(': ');
        const headerName = parts.shift();
        headers[headerName] = parts.join(': ');
    });
    
    return headers;
}

2. Hook Fetch API

const originalFetch = window.fetch;

window.fetch = async function(input, init) {
    const response = await originalFetch(input, init);
    
    // Clone the response to read it without consuming it
    const clonedResponse = response.clone();
    
    // Get response headers as an object
    const headersObj = {};
    clonedResponse.headers.forEach((value, name) => {
        headersObj[name] = value;
    });
    
    console.log('Fetch Request URL:', typeof input === 'string' ? input : input.url);
    console.log('Fetch Response Headers:', headersObj);
    
     return response;
};

3. Service Worker 方案(更高级)

如果是在浏览器扩展或PWA环境中,可以使用Service Worker来拦截所有网络请求:

// service-worker.js
self.addEventListener('fetch', event => {
   event.respondWith(
       fetch(event.request).then(response => {
           // Clone the response to read the headers
           const clonedResponse = response.clone();
           
           // Log all response headers
           clonedResponse.headers.forEach((value, name) => {
               console.log(`Header: ${name} - ${value}`);
           });
           
           return response;
       })
   );
});

注意事项

  1. 同源策略:由于安全限制,你只能访问自己域名的完整响应头。跨域请求通常只能访问部分CORS允许的头信息。

  2. 性能影响:Hook这些方法可能会对应用性能产生轻微影响。

  3. 调试工具:在开发过程中,浏览器开发者工具的网络面板已经提供了完整的请求/响应信息。

  4. 生产环境:在生产环境中使用这些hook技术需要谨慎,可能违反某些网站的使用条款。

  5. 现代框架兼容性:如果你使用的是axios等库,可能需要针对特定库进行hook。

以上代码可以根据你的具体需求进行调整和扩展。


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?