要在上游服务器的HTML响应中注入代码,以动态HOOK通过blob:
URL返回的JS代码中的fetch
请求,需要分步骤解决几个关键问题。以下是详细方案:
1. 核心思路
由于blob:
URL生成的JS代码在独立上下文中执行,直接通过HTML注入的脚本无法直接修改其行为。需通过以下方式间接拦截:
- 重写原生API:在全局作用域中劫持
fetch
,确保后续动态加载的JS代码(包括blob:
中的代码)都使用被Hook的版本。 - 监听DOM变化:通过
MutationObserver
捕获动态创建的<script>
标签或blob:
资源加载事件。
2. 具体实现步骤
(1) 在HTML注入阶段重写全局API
<script>
// 保存原生fetch引用
const nativeFetch = window.fetch;
// 劫持fetch
window.fetch = function(...args) {
console.log('Intercepted fetch:', args);
// 在此可修改请求参数或响应
return nativeFetch.apply(this, args)
.then(response => {
// 可选:修改响应内容
return response;
});
};
// 劫持XMLHttpRequest(如需覆盖XHR请求)
const nativeXHROpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(...args) {
console.log('Intercepted XHR:', args);
nativeXHROpen.apply(this, args);
};
</script>
(2) 监听动态脚本加载
若目标JS代码通过<script>
标签动态插入(例如通过blob:
URL),需监听DOM变化:
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.tagName === 'SCRIPT' && node.src.startsWith('blob:')) {
// 拦截blob脚本的内容(需进一步处理)
interceptBlobScript(node);
}
});
});
});
observer.observe(document.documentElement, {
childList: true,
subtree: true
});
function interceptBlobScript(scriptNode) {
// 方案1:阻止原始脚本执行,替换为自定义逻辑
scriptNode.remove();
// 方案2:获取blob内容并修改(需借助URL.createObjectURL)
fetch(scriptNode.src)
.then(res => res.text())
.then(jsCode => {
const modifiedCode = jsCode.replace(/fetch\(/g, 'window.hookedFetch(');
const blob = new Blob([modifiedCode], { type: 'application/javascript' });
const newScript = document.createElement('script');
newScript.src = URL.createObjectURL(blob);
document.body.appendChild(newScript);
});
}
(3) Service Worker全局拦截(高级方案)
若条件允许,可通过Service Worker拦截所有网络请求(包括blob:
上下文中的请求):
// 注册Service Worker(需HTTPS环境)
navigator.serviceWorker.register('/sw.js').then(() => {
console.log('SW registered');
});
// sw.js文件内容
self.addEventListener('fetch', (event) => {
if (event.request.url.startsWith('https://api.example.com')) {
event.respondWith(
fetch(event.request)
.then(response => modifyResponse(response))
}
});
注意:Service Worker对
blob:
请求的拦截能力有限,通常仅适用于同源HTTP(S)请求。
3. 限制与注意事项
- CSP限制:若目标网站设置了严格的Content Security Policy,可能阻止内联脚本或动态代码执行。
- *绕过方案*:尝试匹配CSP的非ce哈希值或通过服务器代理响应。
- 沙盒环境:某些框架(如Chrome扩展)会隔离执行环境,需使用特定API通信。
- 性能影响:频繁Hook可能引发性能问题,建议仅在调试时启用。
4. 验证是否生效
在浏览器开发者工具中检查:
window.fetch.toString()
确认是否被重写。- Network面板观察请求是否被拦截。
如果仍有未拦截的请求,可能是由于JS代码使用了闭包内的原生fetch
副本。此时需结合AST解析或更复杂的运行时注入技术(如Proxy链)。
内容由零声教学AI助手提供,问题来源于学员提问