javascript - 重置/重新加载 IFrame JavaScript 上下文

标签 javascript html iframe name-collision

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

但是,在执行此操作时,我注意到命名空间冲突是由于用户在其代码中声明的变量将在 IFrame 刷新之间保留下来而发生的。我通过将插入的代码包装到 IIFE 中来修复此问题,但随后注意到,当用户运行循环然后重新加载 IFrame 两次时,将运行两个循环。

显然,IFrame 的 JavaScript 上下文没有被重置。我已经尝试过答案given here包括使用 .contentWindow.location.reload() 重新加载 IFrame以及使用 .src = "about:blank" 更改 IFrame 源但这些只是重置文档的内容,而不是重置 IFrame JavaScript 上下文 according to these answers如果 IFrame 位于同一域中,则持久化。

Here is the actual code that I am working with (克隆存储库 -> 运行 npm install -> 运行 npm run dev -> 打开 examples/Sandbox/index.html )。

以下是该问题的最小可重现示例(依赖于 ID 为 frame 的 IFrame 元素的存在):

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();

See on JSFiddle .

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

预期的行为是 IFrame 内容 JavaScript 上下文应在重新加载之间完全重置。在示例中,仅 2: ...应重复打印到控制台,而不是同时打印 1: ...2: ... 。如何刷新 IFrame,使其 JavaScript 上下文在整个重新加载过程中保留,并且本质上与手动重新加载页面相同?

最佳答案

创建 IFrame 后,您将无法编辑其源代码,以防止人们使用 IFrame 将代码注入(inject)网站以窃取信息等,或创建包含 IFrame 的虚假网站,其中包含恶意代码以保护域的安全。

您必须通过 AJAX 将编辑器中的更新呈现到 PHP 服务器或 Node.js 等后端,或者完全删除 IFrame 元素并通过

创建一个全新的元素
var if = document.createElement("IFRAME");
if.src = /* your code */
var container = document.getElementById("container");

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

container.innerHTML = "";

关于javascript - 重置/重新加载 IFrame JavaScript 上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59702627/

相关文章:

javascript - 通过一组 N 个点绘制一条曲线,其中 N>2

javascript - 在原型(prototype)继承期间创建了多少次父对象

java - 从 onchange 值显示多个具有相同 id 的 div 或 table 内容

jquery-ui - 使用jQuery选择iframe中的表单

javascript - jQuery div 自动滚动

javascript - MVC Bootstrap 部分 View ValidationMessageFor 在加载页面时执行

HTML p 标签采用其父标签的高度,而不是其内容

javascript - 当500个内部服务器来的时候,前端可以做一些事情,因为同时访问量很大

html - 为什么在 iFrame 中加载的网页在 Internet Explorer 7 中没有应用 css

javascript - iframe下#document的处理方法