8

有人声称 eval 是邪恶的。

任何常规 HTML 页面可能如下所示:

        <script src="some-trendy-js-library.js"></script>
    </body>
</html>

也就是说,假设执行此操作的人知道他的工作并将 javascript 留在页面末尾加载。

在这里,我们基本上是将脚本文件加载到 Web 浏览器中。有些人更深入并使用它作为与 3rd 方服务器进行通信的一种方式......

<script src="//foo.com/bar.js"></script>

此时,无论出于何种原因,在运行时有条件地实际加载这些脚本已被发现很重要。

我的观点是什么?虽然机制不同,但我们正在做同样的事情......将一段纯文本作为代码执行 - 也就是eval().


说清楚了,问题来了……

给定某些条件,例如 AJAX 请求,或者(更有趣的是)websocket 连接,执行服务器响应的最佳方式是什么?

这里有一对让你思考......

  • eval()服务器的输出。(那边那个人是不是晕倒了?)
  • 运行服务器返回的命名函数:var resp = sock.msg; myObj[resp]();
  • 构建我自己的解析器来弄清楚服务器试图告诉我什么而不直接弄乱javascript。
4

5 回答 5

5

“邪恶”并不意味着“禁止”。有时,使用所谓的“邪恶”功能是有充分理由的。它们只是被称为“邪恶的”,因为它们可以并且经常被滥用。

在您的情况下,客户端脚本只允许向“它自己的”服务器发出请求。这是原始 JavaScript 来自同一台服务器,因此动态响应与原始代码一样受信任。一个完全有效的场景eval()

于 2012-02-13T19:18:47.233 回答
5

给定某些条件,例如 AJAX 请求,或者(更有趣的是)websocket 连接,执行服务器响应的最佳方式是什么?

对何时用于解析消息结果的主要批评eval是它过于矫枉过正——你正在使用大锤打击苍蝇,而过度使用的工具会带来额外的风险——它们可能会反弹并击中你。

让我们将响应类型分为几个不同的类别:

  1. 按需加载静态javascript
  2. 来自受信任来源在安全通道上的动态响应,其中不包含不受信任方指定的内容。
  3. 来自混合来源的动态响应(可能大部分受信任,但包括不受信任方指定的编码字符串),主要是数据
  4. 基于数据的副作用

eval对于 (1),XHR+和之间没有区别<script src>,但 XHR+eval几乎没有优势。

对于(2),差别不大。如果您可以使用 展开响应,JSON.parse您可能会遇到更少的问题,但是eval与其他方式相比,来自可信来源的数据不太可能滥用额外的权限,所以如果您有充分的积极理由,这没什么大不了的eval.

对于(3),有很大的不同。 eval即使你非常小心,他的过度滥用权威也可能会咬你。这在安全方面是脆弱的。不要这样做。

对于(4),最好能把它分成数据问题和代码问题。如果您可以在执行前验证结果,JSONP 允许这样做。使用或其他几乎没有滥用权限的东西来解析数据JSON.parse,因此您编写并批准用于外部使用的函数会产生副作用。这最大限度地减少了过度滥用的权力。天真eval在这里很危险。

于 2012-02-13T19:19:56.213 回答
4

如果您要从您无法控制的域中获取代码,那么将“原始”代码交给 JavaScript 解释器总是意味着您必须完全信任该域,否则您不必关心恶意代码是否会破坏您的自己的页面。

如果你控制了域,那么就随心所欲。

于 2012-02-13T19:18:19.050 回答
2

服务器应该为您提供数据,而不是代码。您应该让服务器响应您的 JS 代码可以相应执行的 JSON 数据。让服务器发送要调用的函数的名称myObj[resp]();仍然将服务器逻辑与客户端逻辑紧密耦合。

如果没有一些示例代码,很难提供更多建议。

于 2012-02-13T19:18:57.740 回答
2

让您的服务器返回 JSON,并在客户端上解释该 JSON。客户端将弄清楚如何处理 JSON,就像服务器弄清楚如何处理客户端收到的请求一样。

如果您的服务器开始返回可执行代码,那么您就有问题了。不是因为会发生“坏事”(尽管可能),而是因为您的服务器不负责知道客户端是什么或不应该做什么

这就像向服务器发送代码并期望服务器执行它。除非您有一个非常好的理由(例如浏览器内的 IDE),否则这是一个坏主意。

随心所欲地使用eval,只要确保你是分开的责任。

编辑:

我看到了这个逻辑的缺陷。服务器显然是在告诉客户端该做什么,仅仅是因为它提供了客户端执行的脚本。但是,我的观点是服务器端代码不应该即时生成脚本。服务器应该是编排的,而不是生产的。

于 2012-02-13T19:19:10.023 回答