我有一些在客户端(浏览器)和服务器(在
Java Rhino上下文中)运行的
JavaScript函数.这些是小功能 – 基本上是很好的定义,不依赖全局变量或闭包的自定义和可移植的验证器.
以下是一个例子:
function validPhoneFormat(fullObject,value,params,property) { var phonePattern = /^\+?([0-9\- \(\)])*$/; if (value && value.length && !phonePattern.test(value)) return [ {"policyRequirement": "VALID_PHONE_FORMAT"}]; else return []; }
为了保持DRY,我的服务器代码在每个这些函数上都有一个句柄,并调用toString(),并将它们作为JSON对象的一部分返回到浏览器.这样的事情
{ "name" : "phoneNumber","policies" : [ { "policyFunction" : "\nfunction validPhoneFormat(fullObject,property) {\n var phonePattern = /^\\+?([0-9\\- \\(\\)])*$/;\n if (value && value.length && !phonePattern.test(value)) {\n return [{\"policyRequirement\":\"VALID_PHONE_FORMAT\"}];\n } else {\n return [];\n }\n}\n" } ] }
我的浏览器JS代码然后采取此响应,并在该上下文中创建此函数的实例,如下所示:
eval("var policyFunction = " + this.policies[j].policyFunction); policyFailures = policyFunction.call(this,form2js(this.input.closest("form")[0]),this.input.val(),this.property.name));
这一切都很好.然而,我然后通过JSLint运行这个代码,我回到这个消息:
[ERROR] ValidatorsManager.js:142:37:eval是邪恶的
我明白,经常,eval可能是危险的.然而,我不知道如何在不使用它的情况下实现这样的机制.有没有办法我可以做到这一点,也通过JSLint验证器?
解决方法
我不会担心,因为你只是将这些函数字符串从服务器传递给客户端,因此可以控制要评估的内容.
另一方面,如果您正在另一个方向,并在客户端传递的代码在服务器上的evals,那将是一个完全不同的故事…
更新:
由于在注释中禁用验证选项可能会导致您错过未来的错误,而是建议传递函数名称而不是整个函数,并将该函数库镜像到服务器和客户端上.因此,要调用该函数,您将使用以下代码:
var policyFunction = YourLibraryName[this.policies[j].policyFunctionName]; var policyArguments = this.policies[j].policyArguments; policyFunction.apply(this,policyArguments);
更新2:
我能够使用JSLint成功验证以下代码,这本质上允许您在eval适当的大多数情况下“关闭”验证.同时,JSLint仍然会验证普通的eval调用,并且这种方法的所有使用都应该为未来的开发人员提供标志,以避免使用它/在可能的时候重构它/随着时间允许.
var EVAL_IS_BAD__AVOID_THIS = eval; EVAL_IS_BAD__AVOID_THIS(<yourString>);