要 hook 所有 iframe
的 innerHTML
操作,可以通过以下步骤实现:
- 重写
document.createElement
和document.createDocumentFragment
:这将允许你拦截所有新创建的iframe
元素。 - 在每个新的
iframe
加载时进行 hook:可以使用 MutationObserver 来观察文档中添加的所有元素,并对每个新创建的iframe
应用你的 hook。
下面是一个示例代码,演示如何在页面中 hook 所有 iframe
的 innerHTML
:
// Hook innerHTML for all iframes
(function() {
const originalInnerHTML = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'innerHTML');
const hookInnerHTML = function() {
Object.defineProperty(this, 'innerHTML', {
set: function(value) {
console.log('Setting innerHTML to:', value);
originalInnerHTML.set.call(this, value);
},
get: function() {
return originalInnerHTML.get.call(this);
}
});
};
// Hook existing iframes
Array.from(document.querySelectorAll('iframe')).forEach((iframe) => {
try {
hookInnerHTML.call(iframe.contentWindow.document.body);
} catch (e) {
console.warn('Could not hook iframe:', e);
}
});
// Observe new iframes being added to the document
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.tagName === 'IFRAME') {
node.onload = () => {
try {
hookInnerHTML.call(node.contentWindow.document.body);
} catch (e) {
console.warn('Could not hook newly added iframe:', e);
}
};
}
});
});
});
observer.observe(document.body, { childList: true, subtree: true });
})();
// Example of creating an iframe dynamically for testing
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
解释:
hookInnerHTML 函数:这个函数将会被调用,以重写每个 HTML 元素的
innerHTML
属性,并添加相应的 setter 和 getter。Hooking 已存在的
<iframe>
:在初始化时,我们首先选择所有现有的<iframe>
并尝试为它们设置 hooks。MutationObserver:我们使用 MutationObserver 来监视 DOM 中的新节点。如果发现新增了一个
<iframe>
,就给它绑定一个 onload 事件,以便在加载完成后对其进行 hooking。动态创建 iframe 示例:为了测试,我们动态创建了一个
<iframe>
。如果执行此脚本并查看控制台,你应该能够看到对于该<iframe>
的任何内联 HTML 更新都会被捕获到。
注意事项:
- 如果
iframe
指向的是不同源(跨域),则无法访问其内容,可能会导致异常。因此需要做好异常处理和警告。 - 确保浏览器支持 ES6 特性,因为上述代码使用了一些现代 JavaScript 语法。
内容由零声教学AI助手提供,问题来源于学员提问