在 HTML 中 Hook 所有的 fetch
函数(包括主线程和 Web Worker 中的 fetch
)可以通过以下方法实现:
1. Hook 主线程的 fetch
通过覆盖原生的 window.fetch
,可以拦截主线程中的所有 fetch
请求:
// 保存原生 fetch
const originalFetch = window.fetch;
// 覆盖 fetch
window.fetch = async function (...args) {
console.log('Intercepted fetch request:', args);
// 在这里可以修改请求参数、添加 headers、记录日志等
try {
const response = await originalFetch.apply(this, args);
// 在这里可以修改响应内容或记录日志
console.log('Intercepted fetch response:', response);
return response;
} catch (err) {
console.error('Fetch error:', err);
throw err;
}
};
2. Hook Web Worker 中的 fetch
由于 Web Worker 运行在独立上下文中,无法直接通过全局变量覆盖其 fetch
。但可以通过以下方式拦截:
**(1) 使用 Service Worker(推荐)**
Service Worker 是一个网络代理,可以拦截所有网络请求(包括主线程、Worker、甚至 <img>
/ <script>
标签的请求):
// 注册 Service Worker (通常在主线程执行)
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').then(() => {
console.log('Service Worker registered');
});
}
然后在 /sw.js
(Service Worker 脚本)中监听 fetch
:
// sw.js
self.addEventListener('fetch', (event) => {
console.log('Intercepted request:', event.request.url);
// Example: Modify requests or responses
event.respondWith(
fetch(event.request)
.then((response) => {
// Modify response if needed
return response;
})
.catch((err) => {
console.error('Fetch error:', err);
throw err;
})
);
});
优点:
- 全局生效,能捕获所有环境下的请求。
- 无需侵入业务代码。
缺点:
- Service Worker 必须 HTTPS(本地开发可用 HTTP)。
- 需要注册作用域路径,且只能拦截同源或子路径的请求。
(2) Monkey Patch Web Worker
如果无法用 Service Worker,可以在创建 Web Worker 时注入 Hooked Fetch:
// Hook worker.js by modifying its source code before execution
const workerScript = `
// Save original fetch in the worker scope
const originalWorkerFetch = self.fetch;
// Override fetch in the worker
self.fetch = async (...args) => {
console.log('[Worker] Intercepted fetch:', args);
return originalWorkerFetch(...args);
};
${originalWorkerScript} // Your original worker script here
`;
const blob = new Blob([workerScript], { type: 'application/javascript' });
const workerUrl = URL.createObjectURL(blob);
const worker = new Worker(workerUrl);
缺点:
- 侵入性强,需动态修改脚本。
- 不适用于第三方库创建的 Workers。
3. (可选)Hook XMLHttpRequest
如果需要兼容旧的代码或某些库可能使用 XMLHttpRequest
:
const originalXHR = window.XMLHttpRequest;
window.XMLHttpRequest = function () {
const xhr = new originalXHR();
const originalOpen = xhr.open;
xhr.open = function (...args) {
console.log('Intercepted XHR open:', args);
return originalOpen.apply(this, args);
};
return xhr;
};
总结方案对比
方法 | 适用范围 | 侵入性 | 复杂度 |
---|---|---|---|
覆写 window.fetch |
仅主线程 | 低 | 简单 |
Service Worker | 全环境(包括 Workers) | 无 | 中等 |
动态注入 Worker | 特定 Workers | 高 | 较高 |
如果是通用需求,优先选择 Service Worker;若需精准控制某些 Workers,可结合动态注入的方式。
内容由零声教学AI助手提供,问题来源于学员提问