我目前正在开发一个教程网站,用于教授Web开发的基础知识(HTML,CSS和JavaScript,适合初学者)。我想要一个设置,我可以深入介绍各种主题,然后提供一个基本的沙箱环境,用户可以编写代码来解决每个教程部分末尾提出的问题。
例如,如果我在上一个教程中介绍了乘法,并且用户刚刚完成了能够返回值的函数的课程,我可能会要求他们提交一个函数,该函数返回两个参数的乘积。 / p>
这不是完美的实例,其中使用动态函数创建会被认为是个好主意吗?我们来看一个例子。
<script>
function check()
{
eval('var f = ' + document.getElementById('user_code').value);
if (f(5, 10) == 50)
{
// user properly wrote a function which
// returned the product of its parameters
}
}
</script>
这是一个坏主意吗?如果是,请解释。
答案 0 :(得分:1)
听起来你想重新制作Firebug甚至IE8中的新开发者工具。因此,我将不得不说从来没有一个有用的案例。更不用说如果该网站上市,脚本注入的可能性。
答案 1 :(得分:1)
听起来它可以起作用。但是,您环境中的最大挑战可能是错误处理。学生肯定会犯各种错误:
eval()
更精细的方法可能会将输入的Javascript解析为解析树表示,然后将其与预期的解析树进行比较。如果它不匹配,那么指出可能出错的地方并让学生再试一次。如果它匹配,那么您可以eval()
并调用该函数,因为它知道它会按预期执行。
在Javascript中为Javascript实现词法分析器和解析器将具有挑战性,但肯定不是不可能。
答案 2 :(得分:1)
只要您在封闭的环境中操作,就应该工作。 Eval打开你的代码注入攻击,所以我不会把它放在一个可公开访问的网站上,但如果它完全包含在你的教室里你应该没问题。
答案 3 :(得分:1)
代码可以工作,但是如果在语法上或其他方面都有错误怎么办?也许使用try块来捕获任何错误并将其显示给用户会有所帮助......
不确定这是否有帮助。
答案 4 :(得分:1)
在你的情况下,我觉得这没有错。或者,您可以使用new Function()
首先构建内容然后运行它来运行代码。从理论上讲,这将分离“编译”和执行的阶段。但是eval
将首先检查代码并抛出错误:
var usercode = document.getElementById('user_code').value;
try {
var f = new Function( 'a','b','return (' + usercode + ')(a,b);' );
if ( f( 5, 10 ) ) {
// user properly wrote a function which
// returned the product of its parameters
}
else {
// user wrote code that ran but produced incorrect results
}
}
catch ( ex ) {
// user wrote something really bad
}
以这种方式做事的问题在于抛出的异常可能是荒谬的。 "foo;;=bar"
将在括号中报告“缺失”错误,而eval将抛出propper语法错误。您可以通过(regexp)首先从用户代码中获取参数和正文然后构建它来绕过这个。但那么,这会比eval
更好吗?
我认为你真正的问题是帮助用户避免隐式全局变量的陷阱。您是如何帮助用户避免编写仅在第二次运行时才能运行的代码,因为第一次设置了全局?你不需要每次运行都实现干净的沙箱吗?我想看看jsbin.com,firebug和类似工具如何处理这些事情。
我的感觉是你现在应该和eval
一起去,如果有需要的话,可以在以后更改更精细的内容。