是否有任何理由使用动态创建的脚本来执行解决方案?标记而不是eval()

Is there any reason to do a solution using a dynamically created <script> tag instead of eval()?

本文关键字:解决方案 eval 执行 本来 理由 任何 动态 脚本 创建 是否      更新时间:2023-09-26

在JavaScript中避免eval()函数有一些很好的理由,即在eval()代码中包含用户输入时存在安全风险。然而,在eval()代码不包含任何受用户输入影响的情况下(在我的特殊情况下,我们在XML文件中定义了动态模板—这些模板还可以指定复杂的验证函数,嵌入在XML中的javascript代码,然后由客户端通过AJAX接收),有什么理由避免eval()函数吗?

我想到了一个解决方案(我可能不是第一个,但我没有见过这样做),使用动态创建的内联标签代替eval():

$(scriptObject).text(strJSCode);

http://jsfiddle.net/H7EG9/1/可以看到一个简单的示例(我知道这个示例确实使用了用户输入,但这只是为了便于演示)。

有什么理由这样做而不是eval()吗?结果基本上是一样的,尽管对于eval()的死敌来说,这个选项可能看起来不那么"可怕"。

我将使用eval而不是创建脚本标记。

脚本标记会产生开销(它们是DOM元素),但更重要的是,您需要使用某种全局变量来访问脚本标记中的脚本。如果使用eval,可以简单地执行

var evalFunction = eval("(function(){...})"); // wrap function in () to make it an expression
var result = evalFunction(val);

IE8及以下版本不允许以data:格式提供脚本。在这方面,eval()更可靠。

话虽这么说,如果你正在使用AJAX下载一个JS文件,从中你得到的字符串,你可以只是设置scriptObject.src = 'path/to/script.js';浏览器将有缓存中的文件,因此将立即加载它。

eval很容易编写,但在标题或正文中添加一个脚本元素并将js文本附加到新脚本元素中几乎同样容易。有些极端情况,比如变量提升,在执行脚本时表现得有点奇怪。