将任意JavaScript代码存储到字符串变量中

时间:2016-01-04 13:20:08

标签: javascript java clojure nashorn

我有一个程序(用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

3 个答案:

答案 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