执行存储为字符串的JavaScript代码


173

如何执行一些字符串形式的JavaScript?

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    // how do I get a browser to alert('hello')?
}

Answers:



134

您可以使用函数执行它。例:

var theInstructions = "alert('Hello World'); var x = 100";

var F=new Function (theInstructions);

return(F());

3
但最后-与通话不一样var F=function(){eval(theInstructions);};吗?
约恩·伯克费尔德

14
是和否:使用eval代码也将执行,而使用Function()代码直到F()才执行(用例?检查语法错误,但不想执行代码)
G3z 2015年

2
@stefan它的beatifull ...new Function("alert('Hello World');")()
安德烈斯·莫拉莱斯

我在try / catch块中尝试过此方法,它运行完美。现在,我可以将输入到文本块中的所有JavaScript代码传递给我的函数,然后执行它。然后catch块可以将来自JavaScript引擎的错误消息插入DOM元素,并在代码中显示任何错误。如果有人想要我编写的函数,则在整理完之后,可以在此处发布它。
David Edwards

@DavidEdwards如果您仍然拥有并将其发布,将非常棒。
Anoop

60

eval函数将评估传递给它的字符串。

但是使用eval可能会很危险,因此请谨慎使用。

编辑: annakata有一个好处-不仅eval 危险,而且速度。这是因为要评估的代码必须在现场进行解析,这样会占用一些计算资源。


34
超级危险且缓慢-您应使用粗体,斜体,下划线和h1
annakata

5
我怀疑它是否比必须在页面上其他任何地方加载JavaScript都要慢。如果速度较慢,那是因为它是在不同的范围内完成的,这可能会强制为该范围创建资源。
cgp

6
如果你说eval()是危险的。还有其他选择吗?
white_gecko 2012年

4
@coobird我知道这有点晚了,但是为什么这么危险?用户可以使用控制台轻松地在您的网站上运行JavaScript代码。
jkd 2015年

7
如果您的安全性完全取决于客户端javascript,则您已经花了很多时间,而与eval无关。
马修(Matthew)

20

使用eval()。

W3学校评估之旅。网站上有一些可用的评估示例。Mozilla文档对此进行了详细介绍。

您可能会收到很多有关安全使用此软件的警告不允许用户向eval()注入任何内容,因为这是一个巨大的安全问题。

您还想知道eval()的作用域不同。


11
w3fools.com。W3C甚至没有关于评估的任何信息。如果要链接到官方网站,请定位ecma-international.org/ecma-262/5.1/#sec-15.1.2.1
Bergi

7
我不想“链接到任何官方文件,我想链接到可读的文件-查看链接的内容,它没有说明如何使用它,没有示例,没有修补方法,并且单独描述了该方法。对于初学者来说,这是一个完全不合适的链接,嘿,您不会碰巧是@bjorninge,对吗?
cgp

1
该规范eval比W3Schools文章对我的描述更好。具有良好解释和示例的可读性应该是developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。不,我不是bjorninge
Bergi

我会同意这不是文档,我会同意mozilla的页面是一个更好的整体描述。根据反馈略微调整了我的答案
cgp

1
关于ecma-international.org链接,我将其描述为对JS有15分钟以上经验的每个人可读性和可理解性。这是很不错的。
i336_

16

试试这个:

  var script = "<script type='text/javascript'> content </script>";
  //using jquery next
  $('body').append(script);//incorporates and executes inmediatelly

就个人而言,我没有进行测试,但似乎可以工作。


1
您忘记在脚本中转义>了:var script =“ <script type = \” text / javascript \“> content </ script \>”;
rlib

1
为什么您需要转义结束>?
Jools,

11

有点像@Hossein Hajizadeh alerady所说的,尽管更详细:

有一个替代eval()

该函数setTimeout()旨在在毫秒间隔后执行某些操作,而要执行的代码恰好被格式化为字符串。

它将像这样工作:

ExecuteJavascriptString(); //Just for running it

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    setTimeout(s, 1);
}

1 表示它将在执行字符串之前等待1毫秒。

这可能不是最正确的方法,但它可以工作。


当您可以将0(零)传递给时,为什么要浪费一毫秒setTimeout?请注意,无论如何,它将使执行异步。这意味着setTimeout在调用之后的所有代码都将传递给代码之前被调用setTimeout(即使使用0(零)调用)。
jox

just‍♀️只是认为它可以更好地解释setTimeout的工作原理
Anton Juul-Naber

8
new Function('alert("Hello")')();

我认为这是最好的方法。


7

如下使用eval。应谨慎使用eval,有关“ eval is evil ” 的简单搜索应抛出一些指针。

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    eval(s);
}

2
一个关于“评估是邪恶的”简单搜索的好提示, 谢谢!
Taptronic,2009年

5

在许多复杂且模糊的脚本上进行了检查:

var js = "alert('Hello, World!');" // put your JS code here
var oScript = document.createElement("script");
var oScriptText = document.createTextNode(js);
oScript.appendChild(oScriptText);
document.body.appendChild(oScript);

5

如果要在特定时间后执行特定命令(即字符串)-cmd =您的代码-InterVal =延迟运行

 function ExecStr(cmd, InterVal) {
    try {
        setTimeout(function () {
            var F = new Function(cmd);
            return (F());
        }, InterVal);
    } catch (e) { }
}
//sample
ExecStr("alert(20)",500);

@SteelBrain添加一个由ExecStr(“ alert(20)”,500)运行的示例;
侯赛因·哈吉扎德

1
为什么ValInterVal资本?
Redwolf Programs

4

对于正在使用node并关心eval()nodejs提供的上下文含义的用户vm。它创建了一个V8虚拟机,可以在单独的上下文中沙箱化代码的执行。

更进一步,vm2这将使vm虚拟机运行不受信任的代码变得更加困难。

const vm = require('vm');

const x = 1;

const sandbox = { x: 2 };
vm.createContext(sandbox); // Contextify the sandbox.

const code = 'x += 40; var y = 17;';
// `x` and `y` are global variables in the sandboxed environment.
// Initially, x has the value 2 because that is the value of sandbox.x.
vm.runInContext(code, sandbox);

console.log(sandbox.x); // 42
console.log(sandbox.y); // 17

console.log(x); // 1; y is not defined.

2
与其说“评估是邪恶的”,没有给出背景或解决方案,不如说是设法解决问题。为您+1
Redwolf Programs

3
eval(s);

但是,如果您从用户那里获取数据,这可能很危险,尽管我认为如果用户崩溃了,这就是他们的问题。


1
究竟。评估在服务器端很危险。在客户端上...没那么多。用户只需在浏览器和浏览器的地址中输入javascript:someevilcode即可。埃瓦尔就在那里。
Esben Skov Pedersen

@EsbenSkovPedersen至少在chrome中是防止这种情况的,并且它需要用户采取行动,而不是eval从用户那里编写代码的网站,例如,该网站可能使用户窃取其他用户的帐户而使他们仅通过加载页面就不知道。
1j01 2015年

1
@ 1j01说句公道话,我的评论已有五岁了。
Esben Skov Pedersen 2015年

@EsbenSkovPedersen是的:)
1j01

2

不知道这是否在作弊:

window.say = function(a) { alert(a); };

var a = "say('hello')";

var p = /^([^(]*)\('([^']*)'\).*$/;                 // ["say('hello')","say","hello"]

var fn = window[p.exec(a)[1]];                      // get function reference by name

if( typeof(fn) === "function") 
    fn.apply(null, [p.exec(a)[2]]);                 // call it with params


2

我在回答类似的问题,但又有了另一个想法,如何不使用以下方法实现此目的eval()

const source = "alert('test')";
const el = document.createElement("script");
el.src = URL.createObjectURL(new Blob([source], { type: 'text/javascript' }));
document.head.appendChild(el);

在上面的代码中,您基本上创建了包含脚本的Blob,以便创建对象URL(浏览器内存中File或Blob对象的表示形式)。由于您src<script>标签上具有属性,因此脚本的执行方式与从任何其他URL加载脚本的方式相同。


2
function executeScript(source) {
    var script = document.createElement("script");
    script.onload = script.onerror = function(){ this.remove(); };
    script.src = "data:text/plain;base64," + btoa(source);
    document.body.appendChild(script);
}

executeScript("alert('Hello, World!');");


0
eval(s);

但是请记住,该评估功能非常强大且非常不安全。您最好确信所执行的脚本是安全的,并且不会被用户更改。


1
在JS中,用户只需输入“ javascript:document.write(“ Hello World”);“即可更改所有内容。进入几乎所有浏览器的地址栏。
UnkwnTech

1
是的,但是您可以通过不使用全局变量,在闭包中隐藏函数等方式使他更难。而且,避免像瘟疫=那样避免eval
PatrikAkerstrand

0

一个可以使用mathjs

上面链接的摘录:

// evaluate expressions
math.evaluate('sqrt(3^2 + 4^2)')        // 5
math.evaluate('sqrt(-4)')               // 2i
math.evaluate('2 inch to cm')           // 5.08 cm
math.evaluate('cos(45 deg)')            // 0.7071067811865476

// provide a scope
let scope = {
    a: 3,
    b: 4
}
math.evaluate('a * b', scope)           // 12
math.evaluate('c = 2.3 + 4.5', scope)   // 6.8
scope.c                                

scope是任何对象。因此,如果将全局范围传递给evalute函数,则可以动态执行alert()。

而且mathjs比eval()更好,因为它在沙盒中运行。

用户可以尝试通过表达式解析器注入恶意JavaScript代码。mathjs的表达式解析器提供了一个沙盒环境来执行使这不可能的表达式。尽管可能存在未知的安全漏洞,所以请务必小心,尤其是在允许服务器端执行任意表达式的情况下。

较新版本的mathjs不使用eval()或Function()。

解析器主动阻止对JavaScript内部eval和新Function的访问,这是安全攻击的主要原因。Mathjs 4版及更高版本并未在后台使用JavaScript的eval。版本3和更早的版本确实将eval用于编译步骤。这不是直接的安全问题,但会导致更大的攻击面。


0

同时使用eval和创建新函数来执行javascript 会带来很多安全风险。

const script = document.createElement("script");
const stringJquery = '$("#button").on("click", function() {console.log("hit")})';
script.text = stringJquery;
document.body.appendChild(script);

我更喜欢这种方法来执行以字符串形式接收的Javascript。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.