首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重置/重发IFrame JavaScript上下文

重置/重发IFrame JavaScript上下文
EN

Stack Overflow用户
提问于 2020-01-12 09:45:25
回答 1查看 708关注 0票数 0

我正在创建一个由文本框和<iframe>元素组成的交互式代码编辑器。每当用户在文本框中键入代码时,IFrame的内容就会被写入,而IFrame中的<script>标记将被填充到代码文本框的内容中,从而导致用户键入的代码在IFrame中运行。每次用户输入时,都应该重置/重新加载IFrame,并且在IFrame脚本标记中使用文本框的新内容再次写入文档,本质上是在输入时自动运行他们键入的任何代码。

但是,在执行此操作时,我注意到命名空间冲突的出现是因为用户在代码中声明的变量将在IFrame刷新之间持久化。我通过将插入的代码封装到IIFE中来修正这个问题,但是注意到当用户运行一个循环,然后重新加载IFrame两次时,两个循环就会运行。

显然,没有重置IFrame的IFrame上下文。我尝试过答案给在这里,包括使用.contentWindow.location.reload()重新加载IFrame,以及用.src = "about:blank"更改IFrame源代码,但这些只是重置文档的内容,而不是IFrame JavaScript上下文,如果根据这些答案位于相同的域中,根据这些答案就会持久化。

下面是我正在使用的实际代码 (克隆存储库-> Run npm install -> Run npm run dev -> Open examples/Sandbox/index.html)。

下面是这个问题的最小可重现性示例(依赖于ID为IFrame frameframe元素的存在):

代码语言:javascript
复制
const frame = document.getElementById("frame");
let i = 1;

function updateFrame() {
    frame.contentWindow.location.reload();

    frame.contentDocument.open();

    frame.contentDocument.write(`
        <html>
            <body>
                <script>
                    (function() {
                        let a = 0;

                        function print() {
                            console.log(${i++} + ": " + a++);

                            requestAnimationFrame(print);
                        }

                        print();
                    })();
                </script>
            </body>
        </html>
    `);

    frame.contentDocument.close();
}

updateFrame();
updateFrame();

见JSFiddle

注意,updateFrame()被调用了两次,这应该会重新加载IFrame的内容,只剩下第二个循环在运行,但是两个print()循环同时打印到控制台,显示在重新加载过程中上下文保持不变。

预期的行为是,IFrame内容和JavaScript上下文应该在重新加载之间完全重置。在本例中,只应将2: ...反复打印到控制台,而不是同时打印1: ...2: ...。如何刷新IFrame,使其JavaScript上下文是在重新加载过程中持久化的而不是,本质上与手动重新加载页面的操作相同?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-12 10:06:35

一旦创建了IFrame,您就无法编辑它的源代码,以防止人们使用IFrames将代码注入网站,以便窃取信息等,或者创建带有恶意代码的假IFrames网站,以保护域的安全。

您必须通过AJAX将编辑器的更新呈现到后端(如PHP服务器或node.js ),或者完全删除IFrame元素并通过以下方式创建一个全新的元素:

代码语言:javascript
复制
var if = document.createElement("IFRAME");
if.src = /* your code */
var container = document.getElementById("container");

然后,每次需要更新时,都使用类似的系统删除该项。

代码语言:javascript
复制
container.innerHTML = "";
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59702627

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档