我正在寻找最优雅的方式"倾倒"将简单的JavaScript对象转换为动态生成的JavaScript源代码。
目的: 假设我们有node.js服务器生成HTML。我们在服务器端有一个 x 对象。对象很简单 - 只有字符串/整数/数组(因此,它具有JSON功能)。我想"嵌入"将对象x生成为正在生成的HTML,以供可在浏览器上运行的JavaScript代码使用。所以代码:
console.log(x);
将在服务器端和浏览器端转储完全相同的数据。 例如 - 假设我要将一些额外的配置/数据传递给在浏览器上运行的JavaScript。
明显的解决方案:
编码为JSON并简单地附加到变量声音最初很好,但涉及一些额外的转义步骤。
使用util.inspect()对我有用,就这样:
var toHtml =' var x =' + util.inspect(theXonServer,{depth:9})+';';
但我不确定它是否优雅" (并且安全且容易出错......)
有什么更好的建议吗?标准的做法是什么?
答案 0 :(得分:2)
获取建议只是将一些JSON字符串化并将其转储到<script>
标记中是很常见的。 这是一个糟糕的建议 。不要这样做。
了解为什么这是一个坏主意非常重要。
当您使用字符串构建JavaScript时,您可以打开自己的各种语言怪癖,以确保不会出现任何问题。
一个这样的怪癖是,在<script>
元素中,第一次出现</script>
将关闭 <script>
元素。它在字符串中的作用并不重要,脚本将被关闭,并且该点之后的其余内容将被视为HTML。
HTML转义不起作用,因为JS不喜欢HTML实体。
可能的开头是:
<script>
window.xss = <%= JSON HERE %>
</script>
可能变成:
<script>
window.xss = {"username":"Robert Hackerman</script><script src='nefarious.js'></script>"}
</script>
不要冒风险。
阻止任何脚本执行的更安全的方法是通过[data-*]
属性。您必须 HTML-escape内容,但属性正常。我使用<script>
元素,因为它暗示脚本将使用数据。
什么会开始:
<script data-foo="<%= HTML ENCODED JSON HERE %>" src="yourscript.js"></script>
会变成:
<script data-foo="{"username":"Robert Hackerman</script><script src='nefarious.js'></script>"}" src="yourscript.js"></script>
如果您想要访问该数据,您只需访问该属性值,或使用dataset api (if your target browsers support it):
var fooElement = document.querySelector('[data-foo]');
var rawData = fooElement.dataset.foo;
// or
var rawData = fooElement.getAttribute('data-foo');
var data = JSON.parse(rawData);
console.log(data);
如果页面已经加载,并且您想要访问某些数据,只需使用AJAX请求即可。您将能够安全地读入JSON数据源,该数据源可以通过JSON.parse传输以访问数据对象。
答案 1 :(得分:0)
如果您的对象是圆形的,则只需要util.inspect
。如果它在99.9%的情况下可编码JSON,您可以使用JSON.stringify
将其输出到源。
有一些优势 - 不仅JS对象比JSON(函数等)更具表现力,JSON对象可以做JS对象无法做到的事情(在编码的边缘情况下)。因此,请确保您的对象不仅可以正确序列化,而且还可以正确反序列化。我还假设你没有做任何疯狂的事情,比如覆盖数组构造函数(这会使JS对象的行为与JSON不同)。
至于安全性,除非您的对象可以包含敏感数据(并且它确实不应该首先将其列入白名单),否则不应存在任何相关问题。
总体选项2是一种非常常用的标准方法 - 包括在此网站上。