JavaScript eval() 为什么使用eval()是一个坏主意 什么时候可以使用eval()
2017-01-02 11:17
706 查看
----------------------------------------------------------------------------------------------------
JavaScript eval() Function
The eval() function evaluates or executes an argument.
If the argument is an expression, eval() evaluates the expression. If the argument is one or more JavaScript statements, eval() executes the statements.
如果参数是表达式,eval()函数会执行表达式;如果参数是js语句,eval()函数会执行js语句。
----------------------------------------------------------------------------------------------------
MDN文档
The
eval()会“求值计算”一个计算机字符串
The argument of the
eval()函数是全局对象的属性。
eval()函数的参数是字符串。如果是一个代表着表达式的字符串,eval()函数就会“计算求值”这个表达式;如果参数是js语句,eval()函数就会“求值计算”这些语句。不要调用eval()进行算术运算,js在算术运算时会自动调用。
If you construct an arithmetic expression as a string, you can use
If the argument of
In the following example, the
You can work around this limitation in a generic fashion by using
If you use the
如果不是直接调用eval(),而是按照引用调用,则eval()的作用域是全局作用域而不是局部作用域。
Don't use
-----------------------------------------------------------------------------------------------------------------------------
Why is using the JavaScript eval function a bad idea? eval() isn’t evil, just misunderstood
answer1:
Improper use of eval opens up your code for injection attacks(注入攻击)
Debugging can be more challenging(调试困难) (no line numbers, etc.)
eval'd code executes more slowly (no opportunity to compile/cache eval'd code)
Edit: As @Jeff Walden points out in comments, #3 is less true today than it was in 2008(第三点,在现代浏览器中,可能并不会很慢).
However, while some caching of compiled scripts may happen this will only be limited to scripts that are eval'd repeated with no modification. A more likely scenario is that you are eval'ing scripts that have undergone slight modification each time and as such could not be cached. Let's just say that SOME eval'd code executes more slowly.
answer2:
Two points come to mind:
Security (but as long as you generate the string to be evaluated yourself(安全性问题,但是如果参数字符串是你自己产生的,即你能确保它是安全的,则使用eval()是没有问题的), this might be a non-issue)
Performance: until the code to be executed is unknown(性能问题), it cannot be optimized. (about javascript and performance,
answer3:
It's generally only an issue if you're passing eval user input(通常情况下,只有对用户输入使用eval()会产生问题,因为这种情况下你不能确保用户会输入什么).
answer4:
Unless you are 100% sure that the code being evaluated is from a trusted source(如果你不是百分百确定的eval()中的参数是值得信任的,安全的,那么你的系统就很有可能暴露在XSS跨域站点攻击) (usually your own application) then it's a surefire way of exposing your system to a cross-site scripting attack.
Code Injection is a very serious issue for javascript if you are at all concerned about your user's data. Injected code will run (in the browser) as if it came from your site, letting it do any sort of shenanigan that the user could do manually. If you allow (third-party) code to enter you page, it can order things on behalf of your customer, or change their gravatar, or whatever they could do through your site. Be very careful. Letting hackers own your customers is just as bad as letting them own your server.
--------------------------------------------------------------------------------
When is JavaScript's eval() not evil?
answer1:
I'd like to take a moment to address the premise of your question - that eval() is "evil". The word "evil", as used by programming language people, usually means "dangerous", or more precisely "able to cause lots of harm with a simple-looking command". So, when is it OK to use something dangerous? When you know what the danger is, and when you're taking the appropriate precautions.
所以,什么时候使用eval()函数是OK的呢?当你明白危险所在,当你做了一些适当的预防措施时。
To the point, let's look at the dangers in the use of eval(). There are probably many small hidden dangers just like everything else, but the two big risks(使用eval()有两大点风险:1 性能表现 2 注入危险) - the reason why eval() is considered evil - are performance and code injection.
Performance - eval() runs the interpreter/compiler. If your code is compiled(如果你的代码是编译型的,那么“使用”eval()会有性能问题), then this is a big hit, because you need to call a possibly-heavy compiler in the middle of run-time. However, JavaScript is still mostly an interpreted language(js仍旧是解释性语言,所以调用eval()通常情况下并不是一个性能问题), which means that calling eval() is not a big performance hit in the general case (but see my specific remarks below).
Code injection - eval() potentially runs a string of code under elevated privileges. For example, a program running as administrator/root would never want to eval() user input, because that input could potentially be "rm -rf /etc/important-file" or worse. Again, JavaScript in a browser doesn't have that problem, because the program is running in the user's own account anyway. Server-side JavaScript could have that problem(代码注入,服务器端的代码注入会有大的风险).
On to your specific case. From what I understand, you're generating the strings yourself, so assuming you're careful not to allow a string like "rm -rf something-important" to be generated, there's no code injection risk (but please remember, it's very very hard to ensure this in the general case). Also, if you're running in the browser then code injection is a pretty minor risk(如果你在浏览器运行js,那么代码注入是一个相当小的风险), I believe.
As for performance, you'll have to weight that against ease of coding. It is my opinion that if you're parsing the formula, you might as well compute the result during the parse rather than run another parser (the one inside eval()). But it may be easier to code using eval(), and the performance hit will probably be unnoticeable. It looks like eval() in this case is no more evil than any other function that could possibly save you some time.
answer2:
If, for your purpose,
answer3:
When you trust(当你信任数据来源十) the source.
In case of JSON, it is more or less hard to tamper with the source, because it comes from a web server you control. As long as the JSON itself contains no data a user has uploaded, there is no major drawback to use eval.
In all other cases I would go great lengths to ensure user supplied data conforms to my rules before feeding it to eval().
[b]answer4:[/b]
Lets get real folks:
Every major browser now has a built in console which your would-be hacker can use with abundance to invoke any function with any value - why would they bother to use an eval statement - even if they could?
If it takes 0.2s to compile 2000 lines of javascript what is my performance degradation if I eval 4 lines of JSON(如果0.2s可以compile2000行代码,那么我使用eval()处理4行代码会带来多少性能上的减少?)?
Even Crockford's explanation for 'eval is evil' is weak.
As Crockford himself might say "This kind of statement tends to generate irrational neurosis. Don't buy it"
Understanding eval and knowing when it might be useful is way more important. For example eval is a sensible tool for evaluating server responses that were generated by your software.
BTW: Prototype.js calls eval directly 5 times (including in evalJSON() and evalResponse()). JQuery uses it in parseJSON (via Function constructor)
JavaScript eval() Function
The eval() function evaluates or executes an argument.
If the argument is an expression, eval() evaluates the expression. If the argument is one or more JavaScript statements, eval() executes the statements.
如果参数是表达式,eval()函数会执行表达式;如果参数是js语句,eval()函数会执行js语句。
----------------------------------------------------------------------------------------------------
MDN文档
The
eval()function evaluates JavaScript code represented as a string.
eval()会“求值计算”一个计算机字符串
Syntax
eval(string)
Parameters
stringA string representing a JavaScript expression, statement, or sequence of statements. The expression can include variables and properties of existing objects.(表达式可以含有变量或已存在对象的属性)
Return value
The completion value of evaluating the given code. If the completion value is empty,undefinedis returned(如果值为空,就会返回undefined).
Description
eval()is a function property of the global object(全局对象的属性).
The argument of the
eval()function is a string. If the string represents an expression,
eval()evaluates the expression. If the argument represents one or more JavaScript statements,
eval()evaluates the statements. Do not call
eval()to evaluate an arithmetic expression; JavaScript evaluates arithmetic expressions automatically.
eval()函数是全局对象的属性。
eval()函数的参数是字符串。如果是一个代表着表达式的字符串,eval()函数就会“计算求值”这个表达式;如果参数是js语句,eval()函数就会“求值计算”这些语句。不要调用eval()进行算术运算,js在算术运算时会自动调用。
If you construct an arithmetic expression as a string, you can use
eval()to evaluate it at a later time. For example, suppose you have a variable
x. You can postpone evaluation of an expression involving
xby assigning the string value of the expression, say "
3 * x + 2", to a variable, and then calling
eval()at a later point in your script.
If the argument of
eval()is not a string,
eval()returns the argument unchanged(如果参数不是一个字符串类型,会将参数原封不动的返回).
In the following example, the
Stringconstructor is specified, and
eval()returns a
Stringobject rather than evaluating the string.
You can work around this limitation in a generic fashion by using
toString().
If you use the
evalfunction indirectly, by invoking it via a reference other than
eval, as of ECMAScript 5 it works at global scope rather than local scope; this means, for instance, that function declarations create global functions, and that the code being evaluated doesn't have access to local variables within the scope where it's being called.
如果不是直接调用eval(),而是按照引用调用,则eval()的作用域是全局作用域而不是局部作用域。
Don't use eval
needlessly!(如果不是需要,就不要使用eval() )
eval()is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run
eval()with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, third party code can see the scope in which
eval()was invoked, which can lead to possible attacks in ways to which the similar
Functionis not susceptible.
eval()is also generally slower than the alternatives, since it has to invoke the JS interpreter, while many other constructs are optimized by modern JS engines.
-----------------------------------------------------------------------------------------------------------------------------
Why is using the JavaScript eval function a bad idea? eval() isn’t evil, just misunderstood
answer1:
Improper use of eval opens up your code for injection attacks(注入攻击)
Debugging can be more challenging(调试困难) (no line numbers, etc.)
eval'd code executes more slowly (no opportunity to compile/cache eval'd code)
Edit: As @Jeff Walden points out in comments, #3 is less true today than it was in 2008(第三点,在现代浏览器中,可能并不会很慢).
However, while some caching of compiled scripts may happen this will only be limited to scripts that are eval'd repeated with no modification. A more likely scenario is that you are eval'ing scripts that have undergone slight modification each time and as such could not be cached. Let's just say that SOME eval'd code executes more slowly.
answer2:
Two points come to mind:
Security (but as long as you generate the string to be evaluated yourself(安全性问题,但是如果参数字符串是你自己产生的,即你能确保它是安全的,则使用eval()是没有问题的), this might be a non-issue)
Performance: until the code to be executed is unknown(性能问题), it cannot be optimized. (about javascript and performance,
answer3:
It's generally only an issue if you're passing eval user input(通常情况下,只有对用户输入使用eval()会产生问题,因为这种情况下你不能确保用户会输入什么).
answer4:
Unless you are 100% sure that the code being evaluated is from a trusted source(如果你不是百分百确定的eval()中的参数是值得信任的,安全的,那么你的系统就很有可能暴露在XSS跨域站点攻击) (usually your own application) then it's a surefire way of exposing your system to a cross-site scripting attack.
Code Injection is a very serious issue for javascript if you are at all concerned about your user's data. Injected code will run (in the browser) as if it came from your site, letting it do any sort of shenanigan that the user could do manually. If you allow (third-party) code to enter you page, it can order things on behalf of your customer, or change their gravatar, or whatever they could do through your site. Be very careful. Letting hackers own your customers is just as bad as letting them own your server.
--------------------------------------------------------------------------------
When is JavaScript's eval() not evil?
answer1:
I'd like to take a moment to address the premise of your question - that eval() is "evil". The word "evil", as used by programming language people, usually means "dangerous", or more precisely "able to cause lots of harm with a simple-looking command". So, when is it OK to use something dangerous? When you know what the danger is, and when you're taking the appropriate precautions.
所以,什么时候使用eval()函数是OK的呢?当你明白危险所在,当你做了一些适当的预防措施时。
To the point, let's look at the dangers in the use of eval(). There are probably many small hidden dangers just like everything else, but the two big risks(使用eval()有两大点风险:1 性能表现 2 注入危险) - the reason why eval() is considered evil - are performance and code injection.
Performance - eval() runs the interpreter/compiler. If your code is compiled(如果你的代码是编译型的,那么“使用”eval()会有性能问题), then this is a big hit, because you need to call a possibly-heavy compiler in the middle of run-time. However, JavaScript is still mostly an interpreted language(js仍旧是解释性语言,所以调用eval()通常情况下并不是一个性能问题), which means that calling eval() is not a big performance hit in the general case (but see my specific remarks below).
Code injection - eval() potentially runs a string of code under elevated privileges. For example, a program running as administrator/root would never want to eval() user input, because that input could potentially be "rm -rf /etc/important-file" or worse. Again, JavaScript in a browser doesn't have that problem, because the program is running in the user's own account anyway. Server-side JavaScript could have that problem(代码注入,服务器端的代码注入会有大的风险).
On to your specific case. From what I understand, you're generating the strings yourself, so assuming you're careful not to allow a string like "rm -rf something-important" to be generated, there's no code injection risk (but please remember, it's very very hard to ensure this in the general case). Also, if you're running in the browser then code injection is a pretty minor risk(如果你在浏览器运行js,那么代码注入是一个相当小的风险), I believe.
As for performance, you'll have to weight that against ease of coding. It is my opinion that if you're parsing the formula, you might as well compute the result during the parse rather than run another parser (the one inside eval()). But it may be easier to code using eval(), and the performance hit will probably be unnoticeable. It looks like eval() in this case is no more evil than any other function that could possibly save you some time.
answer2:
eval()isn't evil. Or, if it is, it's evil in the same way that reflection, file/network IO, threading, and IPC are "evil" in other languages.
If, for your purpose,
eval()is faster than manual interpretation, or makes your code simpler, or more clear(如果使用eval()比你手动“解释”快,让你代码更简单,更清楚明白)... then you should use it. If neither, then you shouldn't. Simple as that.
answer3:
When you trust(当你信任数据来源十) the source.
In case of JSON, it is more or less hard to tamper with the source, because it comes from a web server you control. As long as the JSON itself contains no data a user has uploaded, there is no major drawback to use eval.
In all other cases I would go great lengths to ensure user supplied data conforms to my rules before feeding it to eval().
[b]answer4:[/b]
Lets get real folks:
Every major browser now has a built in console which your would-be hacker can use with abundance to invoke any function with any value - why would they bother to use an eval statement - even if they could?
If it takes 0.2s to compile 2000 lines of javascript what is my performance degradation if I eval 4 lines of JSON(如果0.2s可以compile2000行代码,那么我使用eval()处理4行代码会带来多少性能上的减少?)?
Even Crockford's explanation for 'eval is evil' is weak.
"eval is Evil The eval function is the most misused feature of JavaScript. Avoid it"
As Crockford himself might say "This kind of statement tends to generate irrational neurosis. Don't buy it"
Understanding eval and knowing when it might be useful is way more important. For example eval is a sensible tool for evaluating server responses that were generated by your software.
BTW: Prototype.js calls eval directly 5 times (including in evalJSON() and evalResponse()). JQuery uses it in parseJSON (via Function constructor)
相关文章推荐
- JavaScript 为什么不要使用 eval
- jquery是JavaScript的一个库,也就是说就算使用jQuery,也要遵守JavaScript的语法,为什么jQuery还有自己的语法?
- 如题,既然直接对一个实例发送方法名就可以调用这个方法,那为什么还要使用performSelector:去调呢?两者u有啥区别
- Java 有几程方法可以实现一个线程?用什么关键字修饰同步?stop()和suspend()为什么不推荐使用?
- chaihuoniu为什么结我的贴:软工版什么时候可以再任命一个大版主?
- 简单的做了一个评分控件,其实还算不上控件,只是用javascript做了一个效果,可以直接放在你的程序中使用。
- 机器学习中使用「正则化来防止过拟合」到底是一个什么原理?为什么正则化项就可以防止过拟合?
- 这几天我写了一个类库,可以提供office编程时使用Word, Excel,PowerPoint等的保存后事件DocumentAfterSave
- 为DataGrid的行添加属性,使其可以使用onmouseover的javascript
- 介绍一个GWT的网站 和 decode javascript.encode using java +FCKEditor 在 jsp中的使用说明
- 使用JavaScript写的一个删除HTML代码的函数
- facade 提供一个接口,通过这个接口,可以使一个子系统更容易使用。
- 一个可以禁用USB存储设备的程序(SetupAPI的使用方法)
- MyPage从Page派生,MyPage总有一个Label控件。以便以后从MyPage派生的页都可以直接使用Label?给个代码例子看看?
- 一个使用GridView显示数据,并且可以进行添加、修改、删除操作的例子
- 一个简单的动态编译器,支持C#和VB.NET。当你想测试一些简单的代码的时候可以使用。
- 为什么要写工作日记及一个在线编辑器的使用
- 为什么一个对象调用的类方法可以访问该类其他对象的私有成员
- 经过测试的 可以使用的远程注入代码!!!!!我的VC里面缺少一个stdafx.h需要拷贝一个到程序
- 安装了dns且可以正常工作为什么还有"没有可以使用的"DNS服务器"的错误