调用绕过eval()的函数

Calling a function bypassing eval()

本文关键字:函数 eval 调用      更新时间:2023-09-26

我正在使用一个使用eval函数的Javascript代码。

eval(myString)

myString=myFunc(arg)的值,我想直接调用myFunc而不使用eval。

我无法控制要调用的函数,因为我将该函数作为字符串(此处为myString)。该函数的参数也是同一字符串的一部分。

那么,有没有什么方法可以在不使用eval的情况下调用所需的函数?

我有点怀疑是否允许用户提供函数名,但是。。。假设函数名在一个变量中,arg值在变量中。吊杆:

var myString = window[fn](arg);

arg可能已经在一个参数中了,所以这很简单。下一部分是引出函数名称。只是一点正则表达式:

var fn = /^([a-z0-9_]+)'(arg')$/i.exec(str)[1];
if (fn && typeof window[fn] === 'function') {
  window[fn](arg);
}

当然,这确实假设函数总是在全局范围内,但如果不是,您应该能够相应地进行调整。此外,我的正则表达式只是我想到的第一个东西。它可能没有涵盖所有可能的函数名。

如果你想将字符串限制为一组特定的函数(你几乎肯定应该这样做),那么一旦你有了函数名:,这也会变得很容易

var allowedFunctions = {fn1: fn1, fn2: fn2, someOtherFunction: function() {} },
    fn = /^([a-z0-9_]+)'(arg')$/i.exec(str)[1];
if (fn && allowedFunctions[fn]) {
    allowedFunctions[fn](arg);
} else {
    // Hah, nice try.
}

(如果arg实际上不是一个变量名,而是某种文字或可能是一个任意表达式,这会变得更复杂,也不那么安全。)

JavaScript除了使用eval之外,不提供任何调用以字符串表示的函数的方法。不过,使用它并没有错。既然你别无选择。

您可能会尝试使用Function:

var sure = function(s) {
  return confirm(s);
};
var str = 'sure("Are you sure?")';
var rtn = new Function('return ' + str)();
alert(rtn);