如何添加全局JavaScript监听器拦截wasm子进程发起的特定域名请求
结论
该需求可实现,首先纠正一个认知误区:浏览器环境不存在curl子进程,wasm本身无原生网络能力,所有对外HTTP请求都依赖浏览器提供的JS网络API实现,你看到的类curl格式是浏览器日志的导出展示格式,实际请求走的是标准fetch/XMLHttpRequest等接口,无需反编译wasm即可完成拦截。
可行解决方案
所有拦截代码必须在引入sdk.js之前执行,避免sdk提前缓存原始API引用导致劫持失效。
方案1:劫持全局fetch API(适配现代Web实现)
// 保存原始fetch引用 const originalFetch = window.fetch; window.fetch = function(input, init) { // 解析请求URL const targetUrl = typeof input === 'string' ? input : input?.url || ''; // 替换为你需要拦截的目标域名 if (targetUrl.includes('your-target-domain.com')) { console.log('拦截到目标请求:', targetUrl); // 可选操作1:直接阻断请求,返回自定义响应 return new Response(JSON.stringify({ code: 0, data: null, msg: '拦截成功' }), { status: 200, headers: { 'Content-Type': 'application/json' } }); // 可选操作2:修改请求参数后正常放行 // init = init || {}; // init.headers['Custom-Header'] = 'test'; // return originalFetch.call(this, input, init); } // 非目标请求直接放行 return originalFetch.apply(this, arguments); };
方案2:劫持全局XMLHttpRequest API(适配老旧实现)
如果目标请求用的是XHR而非fetch,用以下代码实现拦截:
const originalOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url, async, user, pwd) { // 匹配目标域名 if (url.includes('your-target-domain.com')) { console.log('拦截到XHR请求:', url); // 重写send方法自定义返回 this.send = function() { Object.defineProperties(this, { readyState: { value: 4 }, status: { value: 200 }, responseText: { value: JSON.stringify({ code: 0, msg: '拦截成功' }) }, response: { value: JSON.stringify({ code: 0, msg: '拦截成功' }) } }); this.onreadystatechange?.(); this.onload?.(); }; } return originalOpen.apply(this, arguments); };
其他场景适配
如果目标请求走的是WebSocket、navigator.sendBeacon、EventSource等其他网络接口,用同样的重写对应全局方法的逻辑即可实现拦截。
极端不适用场景
只有当wasm运行在你没有代码注入权限的独立上下文(如跨域iframe内部、第三方Service Worker、未暴露修改入口的Shared Worker)时,才会出现拦截失败的情况,普通网页嵌入的sdk几乎不会涉及这类场景。
内容的提问来源于stack exchange,提问作者JOhnlw009a
相关产品推荐
相关产品推荐

