如何将JavaScript对象导出为JavaScript?

时间:2015-05-13 13:18:25

标签: javascript html node.js

我正在寻找最优雅的方式"倾倒"将简单的JavaScript对象转换为动态生成的JavaScript源代码。

目的: 假设我们有node.js服务器生成HTML。我们在服务器端有一个 x 对象。对象很简单 - 只有字符串/整数/数组(因此,它具有JSON功能)。我想"嵌入"将对象x生成为正在生成的HTML,以供可在浏览器上运行的JavaScript代码使用。所以代码:

console.log(x);

将在服务器端和浏览器端转储完全相同的数据。 例如 - 假设我要将一些额外的配置/数据传递给在浏览器上运行的JavaScript。

明显的解决方案

  1. 编码为JSON并作为AJAX / Websocket发送不是此问题的一部分,因为我们必须将对象嵌入HTML中。我不想要额外的HTTP请求 - 所有内容都应该一次性传递。
  2. 编码为JSON并简单地附加到变量声音最初很好,但涉及一些额外的转义步骤。

  3. 使用util.inspect()对我有用,就这样:

    var toHtml =' var x =' + util.inspect(theXonServer,{depth:9})+';';

  4. 但我不确定它是否优雅" (并且安全且容易出错......)

    有什么更好的建议吗?标准的做法是什么?

2 个答案:

答案 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="{&quot;username&quot;:&quot;Robert Hackerman&lt;/script&gt;&lt;script src=&apos;nefarious.js&apos;&gt;&lt;/script&gt;&quot;}" 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 vs JSON.stringify

如果您的对象是圆形的,则只需要util.inspect。如果它在99.9%的情况下可编码JSON,您可以使用JSON.stringify将其输出到源。

使用JSON

有一些优势 - 不仅JS对象比JSON(函数等)更具表现力,JSON对象可以做JS对象无法做到的事情(在编码的边缘情况下)。因此,请确保您的对象不仅可以正确序列化,而且还可以正确反序列化。我还假设你没有做任何疯狂的事情,比如覆盖数组构造函数(这会使JS对象的行为与JSON不同)。

安全

至于安全性,除非您的对象可以包含敏感数据(并且它确实不应该首先将其列入白名单),否则不应存在任何相关问题。

总体选项2是一种非常常用的标准方法 - 包括在此网站上。

  • 它通常适用于您需要共享的大多数数据(数字和字符串)的简单数据。
  • 节省往返费用。
  • 它经常在大型网站和实践中使用。