如果 Worker 是通过常规 URL(而非 Blob URL)加载的脚本,可以通过以下方法 Hook 其中的 fetch
函数。核心思路是 拦截脚本请求并动态注入代码,或通过 Service Worker 劫持网络请求。
方法 1:拦截脚本请求并修改(Man-in-the-Middle)
适用于你能控制 Worker 的加载过程(例如在开发环境或浏览器扩展中)。
步骤
- 覆写
Worker
构造函数,拦截目标 URL。 - 用
fetch
获取原始脚本,并在其中注入 Hook。 - 生成新的 Blob URL,传递给原始
Worker
。
代码实现
// 保存原始的 Worker
const OriginalWorker = window.Worker;
// 覆写 Worker
window.Worker = function (scriptURL) {
if (typeof scriptURL === 'string' && scriptURL.includes('your-target-script.js')) {
// Step1: Fetch the original worker script
fetch(scriptURL)
.then((res) => res.text())
.then((scriptText) => {
// Step2: Inject the fetch hook
const hookedScript = `
// Override fetch
const originalFetch = window.fetch;
window.fetch = function (...args) {
console.log("[Hooked Fetch] Request:", args);
// Add your custom logic here (e.g., modify requests/responses)
return originalFetch.apply(this, args);
};
// Original worker code below
${scriptText}
`;
// Step3: Create a new Blob URL for the modified script
const blob = new Blob([hookedScript], { type: "application/javascript" });
const hookedBlobUrl = URL.createObjectURL(blob);
// Step4: Initialize the Worker with the hooked version
return new OriginalWorker(hookedBlobUrl);
});
} else {
// Fallback to normal behavior for other URLs
return new OriginalWorker(scriptURL);
}
};
✅ 适用场景
- 适用于你能够控制页面逻辑的情况(如调试、安全测试)。
- 可用于 Chrome Extensions(需声明
webRequest
权限)。
❌ 限制
- CSP(内容安全策略)可能阻止修改后的脚本执行。
- 无法用于 HTTPS + Strict CSP 网站。
方法 2:使用 Service Worker 全局劫持 Fetch
如果你不能修改 Worker,但可以注册一个 Service Worker,则可以全局拦截所有 fetch
(包括 Worker)。
步骤
- 注册 Service Worker(作用域必须覆盖目标 Worker)。
- 监听
fetch
事件并篡改请求/响应。
代码实现
(1) Main Thread - Register Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw-proxy.js', { scope: '/' })
.then(() => console.log('SW Registered!'));
}
(2) sw-proxy.js - Intercept Fetch
self.addEventListener('fetch', (event) => {
const url = event.request.url;
// Only intercept specific requests (optional)
if (url.includes('api.example.com')) {
console.log('[SW] Intercepted fetch:', url);
// Optionally modify request/response:
event.respondWith(
fetch(event.request)
.then((response) => {
console.log('[SW] Fetched:', response);
return response;
})
);
}
});
✅ 适用场景
- Works even if you can’t modify the original Worker.
- Can inspect/modify all network requests from Workers.
❌ 限制
- Requires HTTPS (or localhost in dev).
- Cannot directly modify the JS code inside Workers, only their network calls.
方法3:Chrome扩展 + Debugger API(高级方案)
如果上述方法受限,可以使用 Chrome Debugger API (需要扩展权限):
chrome.debugger.attach({ tabId }, "1.0", () => {
chrome.debugger.sendCommand(
{ tabId },
"Debugger.evaluateOnCallFrame",
{
callFrameId,
expression: `
window.fetch = function(...args) {
console.log('Hooked!', args);
return originalFetch(...args);
};
`
}
);
});
⚠️ Requires
debugger
permission and user approval.
总结对比
方法 | 可行性 | 侵入性 | 适用场景 |
---|---|---|---|
MITM Script Injection | ★★★★☆ | High | Dev tools / Extensions |
Service Worker Proxy | ★★★☆☆ | Medium | All pages under SW scope |
Chrome Debugger API | ★★☆☆☆ | Low | Advanced debugging |
选择最适合你的方式!如果有更多细节需求,可以进一步优化方案。
内容由零声教学AI助手提供,问题来源于学员提问