eval()读取函数参数有多糟糕

How bad is eval() to read function parameter

本文关键字:参数 函数 读取 eval      更新时间:2023-09-26

我使用Hopscotch在我的网站上进行导游。现在,您必须创建一个JS对象,该对象将作为调用startTour()函数的参数,该函数将启动Tour。在本例中,通过单击.hopscotch-start链接可以开始游览。

HTML:

<a href="#" class="hopscotch-start" data-name="x">Start tour</a>

JS:

var x = {id: "tour1", steps: [{title: "the title",....}]};
$("a.hopscotch-start").click(function (e) {
  e.preventDefault();
  hopscotch.startTour(eval($(this).data('name'))); // -> startTour(x);
  return false;
}

这到底有多糟糕?我知道eval是"慢"的,但它可以让我灵活地只使用一个通用的点击代码,而不再为此烦恼。实际的安全风险是什么(如果有的话)?这样做会大大降低代码的速度(考虑到代码只是读取要作为变量解析的字符串)。

感谢您的反馈-除了eval之外,任何其他实现相同目标的解决方案都是受欢迎的。

如果有任何东西以任何方式修改了属性的值,那么您现在已经从服务器执行了任意JavaScript。

真正的问题是:为什么

如果使用对象作为查找,则不需要eval:

var data = {
  x: {...},
  y: {...},
  ...
};
$("a.hopscotch-start").click(function (e) {
  e.preventDefault();
  hopscotch.startTour(data[$(this).data('name')]);
}

或者,只在属性本身中内联数据可能是有意义的:

HTML:
<a href="#" class="hopscotch-start" data-hopscotch='{"id":"tour1","steps":[{"title":"the title",...}...]'>Start tour</a>
JS:
$("a.hopscotch-start").click(function (e) {
  e.preventDefault();
  hopscotch.startTour($(this).data('hopscotch'));
}

为什么不创建一个对象并通过键获取它?它将更快更安全:

var tours = {
  x: {id: "tour1", steps: [{title: "the title",....}]},
  y: {id: "tour2", steps: [{title: "the title",....}]}
}
$("a.hopscotch-start").click(function (e) {
  e.preventDefault();
  hopscotch.startTour(tours[$(this).data('name')]); // -> startTour(x);
  return false;
}