我有一个程序(用Clojure编写),它将一些JS代码注入JS函数,然后通过Nashorn进行评估。我无法控制代码传递(它可能包含引号,简单的引号......)。
看起来像这样:
;; Clojure
(eval-str (str "print(evaluateCode(\"" s " \"))"))
// equivalent code in pseudo-js just for those not reading Clojure fluently
evalJS("println(evaluateCode(" + arbitraryJS + "))")
evaluateCode
功能已加载。
// already loaded in Nashorn
function evaluateCode(code) {
// do something with the code
//...
eval(code);
}
这适用于简单程序,例如。如果arbitraryJS = "var a=123; print(a); return a;"
。
但是一旦程序包含引号,它就会中断。恩。 "var a = 123; print("a is now", a);"
注意:实际代码为there。
答案 0 :(得分:2)
你需要转义字符串。在每个"之前放置一个\。 如果你需要\本身使用它双\\
抱歉,我暂时不能发表评论......:/
答案 1 :(得分:1)
我建议逃避引号和反斜杠。我会选择单引号作为JS字符串分隔符,因为在Clojure中你必须使用双引号来分隔字符串:
;; Clojure
(eval-str (str "print(evaluateCode('"
(clojure.string/replace s #"(['\\\\])" "\\\\$1")
"'))"))
查找和替换模式每个都有四个反斜杠。在Clojure中,反斜杠是一个转义字符,它们实际上只表示两个反斜杠。在正则表达式中,反斜杠也是一个转义字符,所以最后它们只表示一个字面反斜杠。所以这意味着"前缀任何反斜杠或用反斜杠引用。"
你不应该担心注释和模板等,因为转义字符只存在于Clojure中(在替换之后),但是在Javascript引擎解析完整字符串的那一刻就解决了。 evaluateCode 函数永远不会看到转义字符,而是 s 的普通值。
示例强>
;; Clojure
(def s "a = 'test'; // 'test' used here")
(eval-str (str "print(evaluateCode('"
(clojure.string/replace s #"(['\\\\])" "\\\\$1")
"'))"))
这将评估为:
(eval-str "print(evaluateCode('a = \\'test\\'; // \\'test\\' used here'))")
请注意,反斜杠在上面的表示中加倍,但这是因为Clojure需要它。实际字符串只有一次出现反斜杠。如果不是调用eval-str
,而是使用相同的参数调用println
,您将获得此输出:
打印(evaluateCode(' a = \'测试\&#39 ;; // \'测试\'此处使用')
这是由Javascript引擎解释的字符串,因此它将反斜杠解释为转义字符,将干净的字符串传递给 evaluateCode 。
因此,如果 evaluateCode 看起来像这样:
function evaluateCode(code) {
alert(code);
}
它会产生此警报:
a =' test&#39 ;; //'测试'在这里使用
因此,在Javascript中根本不存在转义反斜杠。它将看到与Clojure符号 s 所代表的完全相同的值。
答案 2 :(得分:0)
在后端我使用Apache Commons Lang StringUtils,因为其他解决方案不起作用。见here。