ZBLOG

如果不是blob URL,就是一个常规URL,如何做呢?

如果 Worker 是通过常规 URL(而非 Blob URL)加载的脚本,可以通过以下方法 Hook 其中的 fetch 函数。核心思路是 拦截脚本请求并动态注入代码,或通过 Service Worker 劫持网络请求


方法 1:拦截脚本请求并修改(Man-in-the-Middle)

适用于你能控制 Worker 的加载过程(例如在开发环境或浏览器扩展中)。

步骤

  1. 覆写 Worker 构造函数,拦截目标 URL。
  2. fetch 获取原始脚本,并在其中注入 Hook。
  3. 生成新的 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)。

步骤

  1. 注册 Service Worker(作用域必须覆盖目标 Worker)。
  2. 监听 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助手提供,问题来源于学员提问

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?