javascript document.write: Uncaught SyntaxError: Unexpected end of input

时间:2021-07-12 05:02:49

标签: javascript

我尝试开发一个实时代码编辑器。

代码给出了错误:

Uncaught SyntaxError: Unexpected end of input

问题出在哪里或者有什么解决办法?

function compile() {
  let htmlContent = document.getElementById('html');
  let cssContent = document.getElementById('css');
  let jsContent = document.getElementById('js');

  let output = document.getElementById('output');

  output = output.contentWindow || output.contentDocument.document || output.contentDocument;

  let doc = output.document;

  doc.open();
  doc.write(
    `<style>${cssContent.value}</style>
                <body>${htmlContent.value}</body>
                <script>${jsContent.value}</script>`
  );
  doc.close();
}
<textarea id="html" cols="30" rows="10"></textarea>
<textarea id="css" cols="30" rows="10"></textarea>
<textarea id="js" cols="30" rows="10"></textarea>
<button onclick="compile()">Run</button>
<iframe id="output"></iframe>

2 个答案:

答案 0 :(得分:0)

如果您在脚本标签内插入,无论它是引号中的字符串、撇号,甚至是模板文字,它都会关闭脚本标签。你必须逃避它。

 doc.write(
  `<style>${cssContent.value}</style>
   <body>${htmlContent.value}</body>
   <script>${jsContent.value}<\/script>`);

但是,如果您使用外部脚本,它应该可以正常工作而不会转义。

此处有更多讨论:"Unterminated template literal" syntax error when literal contains script tag

答案 1 :(得分:0)

关闭脚本标签

正如@Sanmeet 在他(已删除)的回答中指出的那样,错误是由于没有转义结束脚本标签中的反斜杠引起的:如果 html 解析器解码 <script> 标签,它会将输入缓冲到next </script> 标记并将其传递给 JavaScript 编译器。在这种情况下,它将脚本的剩余部分视为文本并将其放入 body 元素中。

重用变量名和类名

将结束标记转义为 <\/script> 揭示了另一个问题。当 document.open 被调用时,谷歌浏览器不会重新初始化全局变量空间(这是正确的历史做法)。遗憾的是,Firefox 已更改其行为以遵循套件并且不再重新初始化变量。

一种可能的解决方案是在每次点击 iframe 按钮时创建一个新的 run 元素。下面的示例扩展了发布的代码以创建新的 iframe。如果您在 JavaScript 框中声明 letconstclass 标识符,您现在可以重复按下运行按钮而无需更改变量和类名称。

function compile() {
  let htmlContent = document.getElementById('html');
  let cssContent = document.getElementById('css');
  let jsContent = document.getElementById('js');

  let output = document.getElementById('output');
  let replacement = document.createElement('iframe');
  replacement.id = "output";
  output.replaceWith( replacement);
  output = replacement;

  output = output.contentWindow || output.contentDocument.document || output.contentDocument;

  let doc = output.document;

  doc.open();
  doc.write(
    `<style>${cssContent.value}</style>
                <body>${htmlContent.value}</body>
                <script>${jsContent.value}<\/script>`
  );
  doc.close();
}
<textarea id="html" cols="30" rows="10"  placeholder="html..."></textarea>
<textarea id="css" cols="30" rows="10" placeholder="css..."></textarea>
<textarea id="js" cols="30" rows="10" placeholder="js..."></textarea>
<button onclick="compile()">Run</button>
<iframe id="output"></iframe>

代码片段错误

执行该代码段会在尝试访问 doc 时产生安全错误。它在浏览器中按预期工作。