【发布时间】:2009-06-02 12:54:36
【问题描述】:
如何执行一些作为字符串的 JavaScript?
function ExecuteJavascriptString()
{
var s = "alert('hello')";
// how do I get a browser to alert('hello')?
}
【问题讨论】:
标签: javascript
如何执行一些作为字符串的 JavaScript?
function ExecuteJavascriptString()
{
var s = "alert('hello')";
// how do I get a browser to alert('hello')?
}
【问题讨论】:
标签: javascript
使用eval 函数,如:
eval("my script here");
【讨论】:
您可以使用函数执行它。示例:
var theInstructions = "alert('Hello World'); var x = 100";
var F=new Function (theInstructions);
return(F());
【讨论】:
var F=function(){eval(theInstructions);};不一样吗?
new Function("alert('Hello World');")()
eval function 将评估传递给它的字符串。
但使用eval can be dangerous,请谨慎使用。
编辑: annakata 有一个好处——eval 不仅危险,而且很慢。这是因为要评估的代码必须在现场解析,这样会占用一些计算资源。
【讨论】:
eval() 很危险。有没有其他选择?
使用 eval()。
W3 Schools tour of eval。网站有一些可用的 eval 示例。 The Mozilla documentation covers this in detail.
您可能会get a lot of warnings 关于安全地使用它。 不允许用户向 eval() 中注入任何东西,因为这是一个巨大的安全问题。
您还想知道 eval() 有一个不同的scope。
【讨论】:
eval 的描述比 W3Schools 的那篇文章对我来说更好。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 是具有良好解释和示例的可读性。不,我不是 bjorninge
对于使用 node 并且关心eval() 的上下文含义的用户,nodejs 提供vm。它创建了一个 V8 虚拟机,可以在单独的上下文中对代码的执行进行沙箱化处理。
更进一步的是vm2,它强化了vm,允许虚拟机运行不受信任的代码。
https://nodejs.org/api/vm.html - 官方nodejs/vm
https://github.com/patriksimek/vm2 - 扩展 vm2
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.
【讨论】:
试试这个:
var script = "<script type='text/javascript'> content </script>";
//using jquery next
$('body').append(script);//incorporates and executes inmediatelly
就个人而言,我没有测试它,但似乎可以工作。
【讨论】:
new Function('alert("Hello")')();
我认为这是最好的方法。
【讨论】:
有点像 @Hossein Hajizadeh alerady 所说的,但更详细:
eval() 有一个替代方案。
函数setTimeout()被设计为在毫秒间隔后执行某些东西,而要执行的代码恰好被格式化为字符串。
它会像这样工作:
ExecuteJavascriptString(); //Just for running it
function ExecuteJavascriptString()
{
var s = "alert('hello')";
setTimeout(s, 1);
}
1 表示在执行字符串之前会等待 1 毫秒。
这可能不是最正确的方法,但它确实有效。
【讨论】:
setTimeout 时,为什么要浪费一毫秒?请注意,无论如何它都会使执行异步。这意味着setTimeout 调用之后的所有代码都将在传递给setTimeout 的代码之前 被调用(即使使用0(零)调用)。
在许多复杂和混淆的脚本上检查了这一点:
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);
【讨论】:
如下使用eval。应谨慎使用 Eval,对“eval is evil”的简单搜索应该会抛出一些指针。
function ExecuteJavascriptString()
{
var s = "alert('hello')";
eval(s);
}
【讨论】:
New Function 和apply() 也可以一起使用
var a=new Function('alert(1);')
a.apply(null)
【讨论】:
如果你想在一个特定的命令(即字符串)之后执行 特定的时间 - cmd=你的代码 - InterVal=延迟运行
function ExecStr(cmd, InterVal) {
try {
setTimeout(function () {
var F = new Function(cmd);
return (F());
}, InterVal);
} catch (e) { }
}
//sample
ExecStr("alert(20)",500);
【讨论】:
Val 中的InterVal 大写?
eval(s);
但是,如果您从用户那里获取数据,这可能会很危险,尽管我认为如果他们自己的浏览器崩溃了,那就是他们的问题。
【讨论】:
evals 用户代码的网站,例如,这可能让用户在他们不知道的情况下窃取其他用户的帐户只需加载页面。
我正在回答类似的问题,并获得了另一个想法,如何在不使用 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(在浏览器内存中表示文件或 Blob 对象)。由于您在 <script> 标记上具有 src 属性,因此脚本的执行方式与从任何其他 URL 加载的方式相同。
【讨论】:
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!');");
【讨论】:
不确定这是不是作弊:
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
【讨论】:
Stefan's answer的扩展:
//Executes immediately
function stringToFunctionAndExecute(str) {
let func = new Function(str);
return (func()); // <--- note the parenteces
}
//Executes when called
function stringToFunctionOnly(str) {
let func = new Function(str);
return func;
}
// -^-^-^- Functions -^-^-^- (feel free to copy)
// -v-v-v- Explanations -v-v-v- (run code to read easier)
console.log('STEP 1, this executes directly when run:')
let func_A = stringToFunctionAndExecute("console.log('>>> executes immediately <<<')");
console.log("STEP 2, and you can't save it in a variable, calling a() will throw an error, watch:")
try {
func_A();
} catch (error) {
console.log('STEP ERROR, see, it failed', error)
}
console.log('STEP 3, but this will NOT execute directly AND you can save it for later...')
let func_B = stringToFunctionOnly("console.log('>>> executes when called <<<')");
console.log("STEP 4, ...as you see, it only run when it's called for, as is done now:")
func_B();
console.log('STEP 5, TADAAAAA!!')
【讨论】:
eval 应该这样做。
eval(s);
【讨论】:
eval(s);
但请记住,eval 非常强大且非常不安全。您最好确信您正在执行的脚本是安全的,并且不会被用户更改。
【讨论】:
可以使用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() 更好的选择,因为它在沙箱中运行。
用户可能会尝试通过 表达式解析器。 mathjs 的表达式解析器提供了一个沙盒 环境来执行表达式,这应该使这不可能。 虽然可能存在未知的安全漏洞, 所以小心很重要,尤其是在允许服务器端时 执行任意表达式。
较新版本的 mathjs 不使用 eval() 或 Function()。
解析器主动阻止访问 JavaScript 的内部 eval 和 新功能是安全攻击的主要原因。数学 版本 4 和更高版本不使用 JavaScript 的 eval 底层。 版本 3 和更早版本确实使用 eval 进行编译步骤。这不是 直接是一个安全问题,但会导致更大的可能攻击 表面。
【讨论】:
同时使用 eval 和创建一个新的 Function 来执行 javascript comes with a lot of security risks.
const script = document.createElement("script");
const stringJquery = '$("#button").on("click", function() {console.log("hit")})';
script.text = stringJquery;
document.body.appendChild(script);
我更喜欢这种方法来执行我收到的字符串形式的 Javascript。
【讨论】: