如何将JavaScript对象导出为JavaScript?

我正在寻找最简单的方法,将简单的JavaScript对象“转储”为正在生成的JavaScript源代码。

目的 :假设我们有生成HTML的node.js服务器。 我们在服务器端有一个对象x 。 该对象很简单 – 只有string/ ints /数组(所以,它是JSON能够)。 我想将object xembedded到生成的HTML中,以便在浏览器上运行JavaScript代码。 所以代码:

console.log(x); 

将在服务器端和浏览器端都转储完全相同的数据。 例如 – 想象一下,我将传递一些额外的configuration/数据到浏览器上运行的JavaScript。

明显的解决scheme

  1. 编码为JSON并发送为AJAX / Websocket不是这个问题的一部分,因为我们必须在HTML中embedded对象。 我不想额外的HTTP请求 – 一切都应该一次通过。
  2. 编码为JSON,只需附加到variables的声音最初是好的,但涉及一些额外的逃逸步骤。

  3. 使用util.inspect()对我来说是这样工作的:

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

但我不知道它是否“优雅”(安全和容易出错,…)

有更好的build议吗? 标准的做法呢?

传递数据的错误方法

获取build议只是将一些JSONstring化并将其转储到<script>标记中是很常见的。 这是不好的build议 。 不要这样做。

理解为什么这是一个坏主意很重要。

当你使用stringbuild立JavaScript的时候,你会打开各种你绝对需要理解的语言怪癖,以确保没有任何问题。

其中一个怪癖是,在<script>元素中,第一个</script>closures <script>元素。 没关系,它是在一个string中,脚本将被closures,其余的内容将被视为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转义的内容,但这是可以的属性。 我正在使用<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> 

如果你想访问这些数据,你可以访问属性值,或者使用数据集api(如果你的目标浏览器支持的话) :

 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进行pipe道访问数据对象。

Util.inspect vs JSON.stringify

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

使用JSON

这里有一些边缘情况 – 不仅JS对象比JSON(函数等)更具performance力,JSON对象可以做JS对象无法做的事情(在编码的边缘情况下)。 所以请确保您的对象不仅是正确的序列化,也正确地反序列化。 我也假设你没有做任何像重写数组构造函数(这将使JS对象与JSON行为不同)的疯狂。

安全

至于安全性方面,除非您的对象可以包含敏感数据(实际上不应该,请先将其列入白名单),否则不应该有任何相关的问题。

总体选项2是一个相当常用的标准方法 – 包括在这个网站上。

  • 它通常适用于需要共享的大部分数据(数字和string)的简单数据。
  • 它节省了往返。
  • 它经常在大的网站和实践中使用。