繁体   English   中英

如何将JavaScript对象导出为JavaScript?

[英]How to export JavaScript object as JavaScript?

我正在寻找将“简单” 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})+';';

但我不确定它是否“优雅”(安全且容易出错,...)

还有更好的建议吗? 这样做的标准方法是什么?

错误的数据传递方式

通常会得到建议,只是将一些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转义,但这在属性中是可以的。 我使用的是<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通过管道进行访问以访问数据对象。

Util.inspect与JSON.stringify

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

使用JSON

这有一些极端的情况-不仅JS对象比JSON(函数等)更具表现力,而且JSON对象可以做JS对象不能做的事情(在编码的极端情况下)。 因此,请确保您的对象不仅可以正确序列化,而且可以正确地反序列化。 我还假设您没有做任何疯狂的事情,例如重写数组构造函数(这会使JS对象的行为不同于JSON对象)。

安全

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

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

  • 它通常适用于简单数据,这是您需要共享的大多数数据(数字和字符串)。
  • 这样可以节省往返行程。
  • 它在大型站点和实践中经常使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM