Javascript eval 的替代方案
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7127652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Alternatives for Javascript eval
提问by Tony Stark
Mozilla's Content Security Policydisallows the use of javascript eval function as well as inline scripts. They claim that all instances of eval can be replaced by another (hopefully safer) function. I agree in most scenarios, Javascript eval can be replaced, but I'm not sure whether the replacement is possible for every case.
Mozilla 的内容安全策略禁止使用 javascript eval 函数以及内联脚本。他们声称所有 eval 实例都可以被另一个(希望更安全的)函数替换。我同意在大多数情况下,可以替换 Javascript eval,但我不确定是否可以在每种情况下替换。
My question is twofold:
我的问题是双重的:
- Is there a generic way to replace every javascript eval function? (doesn't have to be safe)
- Is there a case where the Javascript eval cannot be replaced?
- 有没有通用的方法来替换每个 javascript eval 函数?(不一定要安全)
- 是否存在无法替换 Javascript eval 的情况?
回答by pimvdb
The most common uses which can be substituted are the following ones. I would certainly use these first.
可以替代的最常见用途如下。我肯定会首先使用这些。
Accessing dynamic properties
Do use:
obj[keyAsVariable]
Don't use
eval('obj.' + keyAsVariable)
Parsing JSON
Do use
JSON.parse(data)
Don't use
eval('(' + data + ')')
Calculating user input
Do use a certain library
Don't use
eval(input)
访问动态属性
使用:
obj[keyAsVariable]
不要使用
eval('obj.' + keyAsVariable)
解析 JSON
使用
JSON.parse(data)
不要使用
eval('(' + data + ')')
计算用户输入
使用某个库
不要使用
eval(input)
If really necessary, you can also send the script to a server which simply echoes it back, and you can request it as a script tag. It won't use eval
but still execute it. It isn't safe as it's sent twice over the Internet.
如果真的有必要,您还可以将脚本发送到服务器,服务器会简单地将其回显,然后您可以将其作为脚本标签进行请求。它不会使用eval
但仍会执行它。它不安全,因为它通过 Internet 发送了两次。
var s = document.createElement('script')
s.src = 'request_script?data=' + data;
document.getElementsByTagName('head')[0].appendChild(s);
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
.
request_script
可以是用 PHP 实现的文件,如下所示。同样,这是不好的做法,但它是规避eval
.
<?
echo $_GET['data'];
?>
You could say that this also automatically answers your second question with 'no'.
您可以说这也会自动用“否”回答您的第二个问题。
回答by secretformula
You could wrap the java script within a function call similar to JSONP and then dynamically create a script tag to load that.
您可以将 java 脚本包装在类似于 JSONP 的函数调用中,然后动态创建一个脚本标记来加载它。
回答by Wilt
Load as script using a Blob
使用 Blob 作为脚本加载
Instead of using eval
you can also use a Blob
and load the code as if it was an external js
file:
To ensure that functions or variables that are inside the code that you are loading are available you need to use a callback
method that will be triggered onload
event.
除了使用,eval
您还可以使用 aBlob
并像加载外部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);
NoteBe aware that the danger for code injection is similar to eval.
注意请注意,代码注入的危险与 eval 相似。