我正在为学生(第二语言,9到12岁)转换教程,以便在离线/内联网环境中进行访问。因此,我希望他们使用的网站不可用。
我正在尝试模仿用于帮助JavaScript / HTML5 Canvas的“改变代码”风格的教程。
这有效:
<canvas id="myCanvas" height="400px" width="400px"></canvas>
<script>
function update(){
eval(document.getElementById('demoScript').value);
}
var ctx = document.getElementById("myCanvas").getContext("2d");
</script>
<textarea id="demoScript">
ctx.fillRect(100,100,50,50);
</textarea>
<input type="button" value="update" onClick="update()">
...但我读过的所有内容都说eval()是一个坏主意。
如果我愿意的话,我可以在div中弹出textarea内容,但我无法在任何地方弹出一个脚本...只留下eval()。
替代方案的选项和建议请......或者这是最好的吗?
答案 0 :(得分:1)
这是eval
的可接受用途,因为在最坏的情况下,学生会以无限循环锁定自己的浏览器。
答案 1 :(得分:1)
首先,使用eval并不是一个“坏主意”。 第二:替换eval的任何东西都会有相同的“缺点”,因为它执行代码。您必须执行代码才能执行此操作。如果你不想制作自己的翻译(至少十倍以上,更容易受到攻击),你必须坚持使用eval或类似的东西。
现在有什么危险?除此之外,它执行代码的事实。这就像告诉别人锤子是危险的,因为它很难 - 是的,而且当它被钉住东西时它是必要的。当然,锤子可以杀死。
所以,
您可以为用户限制很多内容,例如每行只有一条指令,只有双引号等,以使其更易于控制。任何超出限制的内容都将被删除。如果没有危险的东西可以通过输入推动,eval是无害的。
答案 2 :(得分:1)
替代方案的选项和建议请......或者这是最好的吗?
我建议使用Function
构造函数而不是eval
。虽然在你的简单例子中它可能没有太大的区别,但在其他情况下可能会有所不同。
这将使代码在全局范围内进行评估,因此无法触及任何局部变量。它还允许JS引擎更轻松地优化本地代码。使用eval()
可以禁用优化。
因此,要使用Function
构造函数,只需将代码作为最后一个参数传递给eval。由于没有为新函数定义的参数,因此它将是唯一的参数。
var f = new Function("return " + document.getElementById("demoScript").value);
然后调用该函数。
f();
请注意,我将return
语句连接到提供的代码中。如果您不关心从调用的代码中获取返回值,则不需要这样做,如果它可能会干扰提供的代码,则应将其删除。
当然,如果你只想调用一次,你可以在一行中完成这一切。
new Function(document.getElementById("demoScript").value)();
答案 3 :(得分:0)
您可以从textarea获取值字符串,拆分,验证并手动运行
对于这样的演示,在给出ctx
的情况下,这样的事情应该起作用
var ctx = document.getElementById("myCanvas").getContext("2d");
function update(){
var val = document.getElementById('demoScript').value,
fn = val.match(/\.(.*?)\(/),
arg = val.match(/\((.*?)\)/);
if (fn && fn.length > 0) {
if (arg && arg.length > 0) {
var args = arg[1].indexOf(',') != -1 ? arg[1].split(',') : [arg[1]];
ctx[fn[1]].apply(ctx, args);
}else{
ctx[fn[1]]();
}
}
}
答案 4 :(得分:-1)
你可以做到
var fn = document.getElementById("demoScript").value;
window[fn]();