From 677dd2f2a3ce037af9e7fff8821f214b8bc515d5 Mon Sep 17 00:00:00 2001 From: chenjianping Date: Sat, 28 Feb 2026 09:23:21 +0800 Subject: [PATCH] fix: prevent stack overflow in nested iframe scenarios MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed circular reference issue in getElementQueryTarget function that caused "Maximum call stack size exceeded" errors in multi-level nested iframe applications. Problem: When using iframe sandbox mode with three-layer nesting (A→B→C), accessing document.body in getElementQueryTarget triggered the proxied getter, which called querySelector, leading to infinite recursion: document.body getter → querySelector → getElementQueryTarget → document.body Solution: Use globalEnv.rawDocument.body/head instead of document.body/head to avoid triggering proxied getters and prevent circular calls. Changes: - src/source/patch.ts: Modified getElementQueryTarget to use rawDocument Tested in three-layer nested scenario with iframe sandbox mode. --- src/source/patch.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/source/patch.ts b/src/source/patch.ts index a37fc900..007811fb 100644 --- a/src/source/patch.ts +++ b/src/source/patch.ts @@ -478,12 +478,15 @@ export function patchElementAndDocument(): void { */ function getElementQueryTarget(targetNode: Node): Node | null { const currentAppName = getIframeCurrentAppName() || getCurrentAppName() - if ((targetNode === document.body || targetNode === document.head) && currentAppName) { + // 使用 rawDocument 避免触发被代理的 document.body/head getter,防止循环引用 + const rawBody = globalEnv.rawDocument.body + const rawHead = globalEnv.rawDocument.head + if ((targetNode === rawBody || targetNode === rawHead) && currentAppName) { const app = appInstanceMap.get(currentAppName) if (app?.container) { - if (targetNode === document.body) { + if (targetNode === rawBody) { return app.querySelector('micro-app-body') - } else if (targetNode === document.head) { + } else if (targetNode === rawHead) { return app.querySelector('micro-app-head') } }