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;
})
);
});
注意事项
同源策略:由于安全限制,你只能访问自己域名的完整响应头。跨域请求通常只能访问部分CORS允许的头信息。
性能影响:Hook这些方法可能会对应用性能产生轻微影响。
调试工具:在开发过程中,浏览器开发者工具的网络面板已经提供了完整的请求/响应信息。
生产环境:在生产环境中使用这些hook技术需要谨慎,可能违反某些网站的使用条款。
现代框架兼容性:如果你使用的是axios等库,可能需要针对特定库进行hook。
以上代码可以根据你的具体需求进行调整和扩展。
内容由零声教学AI助手提供,问题来源于学员提问