javascript - 将字符串附加到 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);
上面的这段代码实际上工作正常。运行时,我可以#myElement
在 DOM 中看到附加的内容,它包含我的字符串化模拟对象。
但是它也会引发错误:
VM136:1 未捕获的 SyntaxError:意外的令牌“:”
此错误似乎专门在脚本的最后一行运行。我很困惑,因为:
不在那条线上。但我意识到它实际上将字符串化处理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>
元素。
一个有点肮脏的技巧是type
在脚本元素上设置一个属性来声明它不是 JavaScript。
推荐阅读
- python - 熊猫删除导致新行的换行符
- apache-kafka - Kafka Streams - 抑制直到窗口结束(不关闭)
- windows-installer - 使用 powershell 在特定驱动器上安装 msi
- python - 如何解决这个 broyden1 np.ndarray 调用问题?
- php - 数据库表,如果值为Not Null,则显示特定图像
- asp.net - 在 ASP.NET 和 ASP.NET Core 应用程序中共享表单身份验证
- elasticsearch - elasticserach / 允许文本和对象在同一个字段中
- database - PostgreSQL:将数据保存在 Docker 容器之外
- javascript - 使用 .map() 将数组替换为嵌套 JSON 对象中的长度
- uart - MSP430FR5994 UART 与 Python 中的 PC 通信