Mozilla的内容安全策略禁止使用javascript eval函数和内联脚本。他们声称所有eval实例都可以被另一个(希望更安全的)函数替换。在大多数情况下,我同意Javascript eval可以被替换,但我不确定是否每种情况都可以替换。
我的问题有两个方面:
- 是否有一种通用方法来替换每个javascript eval函数?(不必安全)
- 是否存在Javascript eval无法替换的情况?
Mozilla的内容安全策略禁止使用javascript eval函数和内联脚本。他们声称所有eval实例都可以被另一个(希望更安全的)函数替换。在大多数情况下,我同意Javascript eval可以被替换,但我不确定是否每种情况都可以替换。
我的问题有两个方面:
以下是可替换的最常见用法,我会优先使用这些用法。
访问动态属性
建议使用: obj[keyAsVariable]
不要使用: eval('obj.' + keyAsVariable)
解析JSON
建议使用: JSON.parse(data)
不要使用: eval('(' + data + ')')
计算用户输入
建议使用某个库
不要使用:eval(input)
如果真的必须要,您可以将脚本发送到一个简单地将其回显的服务器,然后可以将其作为脚本标记请求。它不会使用 eval
但仍会执行它。由于它通过互联网发送两次,因此不安全。
var s = document.createElement('script')
s.src = 'request_script?data=' + data;
document.getElementsByTagName('head')[0].appendChild(s);
request_script
可以是一个用 PHP 实现的文件,例如以下代码。尽管这样做是不好的实践,但它是绕过 eval
的一种通用方式。
request_script
could be a file implemented in PHP, like the following. Again, it's bad practice but is a generic way of circumventing eval
.
<?
echo $_GET['data'];
?>
你可以说这也自动回答了你的第二个问题,即“否”。
不要使用eval
,你可以使用Blob
并将代码作为外部js
文件进行加载:
为了确保加载的代码中的函数或变量可用,需要使用callback
方法,在onload
事件触发时调用。
var code = "console.log('hello world');";
// With eval:
eval(code);
// With a blob:
var blob = new Blob([code], {type: 'text/javascript'});
var urlCreator = window.URL || window.webkitURL;
var url = urlCreator.createObjectURL( blob );
function loadScript(url, callback)
{
// Add a the script tag to the head
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Bind the callback (depends on browser compatibility).
script.onreadystatechange = callback;
script.onload = callback;
// Load the script
head.appendChild(script);
}
// Any variables or methods inside the code will be on callback.
loadScript(url, callback);
注意:要知道代码注入的风险类似于eval函数。
code
需要接收一个参数并且具有返回值,需要进行哪些修改? - lifebalance您可以将JavaScript代码包装在一个类似于JSONP的函数调用中,然后动态创建一个脚本标记来加载它。
var test = "hello world";
,你可以将其转换为 function go() { var test = "hello world" }
,然后动态生成一个脚本标签来加载该代码,这将被评估。 - secretformula
eval
到其他语言结构的通用转换? - Daniel Prydeneval
。 - lifebalance