我从远程处理函数(clojurescriptone)中查看此代码,其中正在读取从浏览器发回的数据。我的问题是将read-eval设置为false的意义是什么?
(绑定[ read-eval false](读取字符串数据))
谢谢, 穆尔塔扎
答案 0 :(得分:9)
这是一种安全措施,因此浏览器无法发送要在服务器中执行的代码。例如,如果客户端/浏览器发送"#=(eval (System/exit 1))"
并且* read-eval *为true,则服务器进程将退出,这可能是您不想要的。
查看行为的差异:
(binding [*read-eval* false] (read-string "#=(eval (System/exit 1))"))
(binding [*read-eval* true] (read-string "#=(eval (System/exit 1))"))
另请参阅*read-eval*上的文档。
答案 1 :(得分:4)
*read-eval*
的主要目的是允许读者在读取时评估表达式,通常用于没有文字符号的内容。如果*read-eval*
为真(默认值),read
和read-string
将评估#=后面的表达式。您可以看到当*print-dup*
绑定为true时如何使用该功能 - 这意味着您希望以保持其精确类型的方式打印值,在这种情况下,您将看到使用#=打印的某些值符号。 *print-dup*
的默认值为false - 对于大多数情况,标准Clojure表示法很好。例如,我们通常不关心Integers和Longs之间的区别。
*read-eval*
功能对于加载代码很有用,但与不受信任的输入一起使用时会产生安全风险。 Clojure 1.5之前的通常建议是在处理用户输入时绑定*read-eval*
false。但是,读取可能导致问题的Java对象仍然存在一些问题。这在Clojure 1.5中得到了修复。更重要的是,引入了Clojure 1.5,clojure.edn/read
和clojure.edn/read-string
,它们不支持任何*read-eval*
功能。它们对于读取表示EDN格式定义的通常Clojure值的用户输入是安全的。有关详细信息,请参阅http://edn-format.org。