将字符串附加到DOM会转换为JSON

问题描述

我正在尝试为单元测试编写一个快速的模拟功能。为了测试我的断言,我需要在页面添加一个HTML元素,并且该元素包含字符串化的JSON。被测系统采用字符串化的JSON,对其进行修改,然后将其转换回并重新插入。

在DOM中创建模拟插入时,我发现一个奇怪的地方,当我访问字符串化的JSON时,好像只是一个字符串时实际上是JSON。

这是代码示例

var mockJson = JSON.stringify({
    name: "Foo",data: {}
});
var mockScript = document.createElement("script");
mockScript.id = "myElement";
mockScript.textContent = mockJson;
document.body.appendChild(mockScript);

上面的代码实际上可以正常工作。运行时,我可以在DOM中看到附加的#myElement,其中包含我的字符串化模拟对象。

但是它也会引发错误

VM136:1未捕获的语法错误:意外的令牌':'

错误似乎专门在脚本的最后一行上运行。我很困惑,因为:不在那一行。但是我意识到这实际上是将字符串化的mockJson当作JSON ...,但同时运行良好。

我测试了删除复杂的模拟对象并将其替换为简单的字符串:

var mockJson = "foo";
var mockScript = document.createElement("script");
mockScript.id = "myElement";
mockScript.textContent = mockJson;
document.body.appendChild(mockScript);

在运行该脚本时,它仍然可以完成预期的工作,我的脚本元素在DOM中显示,其中包含字符串“ foo”。但是在这种情况下也会出现一个错误

VM179:1未捕获的ReferenceError:未定义foo

因此,尽管它被声明为字符串,它仍试图将foo插入为变量。

为什么会这样?为什么既要同时按预期将其添加为字符串,又抛出此错误

小提琴示例

    var mockJson = JSON.stringify({
        name: "Foo",data: {}
    });
    var mockScript = document.createElement("script");
    mockScript.id = "myElement";
    mockScript.textContent = mockJson;
    document.body.appendChild(mockScript);

解决方法

这与将数据附加到DOM无关。这就是将JSON放入脚本元素时发生的情况。

脚本元素应包含 JavaScript ,而不是JSON。

字符串文字是一个完全有效(尽管完全没有意义的)JavaScript表达式。

"A string"

对象文字不是。

{ "property": "value","second property": "value" }

这是因为语法{}用于对象文字和块。在这种情况下,它被视为。第一个属性是标签。它后面的字符串是无意义的字符串(如上例所示)。然后下一个:触发错误。

如果要将JSON添加到页面以进行自动测试,请在有意义的地方使用一个元素。例如,使用<pre>元素而不是<script>元素。

一个有点肮脏的技巧是在script元素上设置type属性,以声明它不是JavaScript。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...