我正在创建一个网站,在我加载静态容器页面后,我正在执行ajax请求以加载一些动态内容。基本上,我需要从服务器传递一个整数数组到页面,我正在使用jQuery来加载数据。我在具有已知名称的标签内写入int,并使用eval从中读取数据。这是一个示例标记(从ajax返回):
<span runat="server" class="hidden" id="PhotoList" />
使用codebehind list.ForEach(p => { sb.Append(p.ID.ToString() + ","); } );
,其中sb是一个StringBuilder,因此服务器作为结果返回如下内容:
<span runat="server" class="hidden" id="PhotoList">1,4,5,42,9</span>
我在javascript中声明了变量photoList
,我调用了var scriptToEval = "photoList = [" + $("#PhotoList").html() + "];";
eval(scriptToEval);
我不是Javascript的主人,我只是想确保这是安全的,因为有很多关于eval
是否安全的讨论。我认为这是安全的(我粘贴的是我使用eval的所有代码),但我可能错过了一点,所以专业人士的意见对我很重要。我知道为什么他们说eval是危险的,因为它能够解释任何恶意与否的代码,但在这里,我认为这种方式根本无法妥协,因为来自服务器的响应完全在我的控制之下。另一种选择是对变量进行另一个ajax调用并直接加载它们而不从返回的数组中获取ajax,但是它会总结为两个调用,(我已经进行了加载调用,因为它确实从服务器加载了一些HTML内容)但是这样,即使有点hacky(将变量放入隐藏的HTML标记),看起来也很方便(毕竟ASP.NET也是为viewstate做的!)。
无论如何,我的重点是eval,这是非常安全的,还是应该考虑一些安全性? Javascript专家请。
答案 0 :(得分:5)
如果您确定数据是安全的,那么eval()
就足够了。
如果您不确定,可以使用JSON.parse()
来处理它:
var arr = JSON.parse( "[" + $("#PhotoList").html() + "]" );
对于不支持JSON
的浏览器,您可以添加json2库。
另一种可能性是对项目进行split()
循环,将它们转换为字符串中的数字。
var arr = $("#PhotoList").html().split(',');
for( var i = 0, len = arr.length; i < len; i++ ) {
arr[i] = parseInt( arr[i], 10 );
}
编辑:由于您使用的是jQuery,如果由于某种原因您真的不想.eval()
,请使用jQuery.parseJSON()
[docs]方法。
var arr = jQuery.parseJSON("[" + $("#PhotoList").html() + "]");
编辑2:另一种方法是使用.replace()
,将函数作为替换值传递。这将为您处理迭代。
var arr = [];
$("#PhotoList").html().replace(/\d+/g, function( s ) { arr.push( parseInt(s,10) ); });
......有很多方法可以做到。
答案 1 :(得分:2)
当然不安全。使用调试器停止代码并更改元素的内容或脚本使用的变量非常容易。
您需要考虑的是您使用数据的内容。如果有人更改了数据,是否可以使用它来访问不可用的内容,还是可以用它来破坏服务器上的任何数据?
如果更改数据只影响页面上显示的内容,那么数据可以更改不是问题。
答案 2 :(得分:1)
安全,是的,假设您的服务器是安全的。通常,您希望真正避免使用eval()
的唯一时间是用户能够添加其他用户可以看到的代码。就像你在展示论坛帖子等时从未想过使用eval()
一样。如果代码来自你的服务器,或者用户的输入只是显示给他/她自己,{{1}很好。这基本上是jsfiddle所做的。
答案 3 :(得分:0)
代码
var result = eval(code);
可能会随
而改变var result = new Function('return '+code+');
答案 4 :(得分:0)
虽然可以在这种情况下使用eval,但我仍然不推荐它,因为它可以产生许多微妙的错误和性能问题。 几乎从不使用eval是一个好主意!
此外,您可以在没有eval的情况下做您想做的事情:
1 - 要设置全局变量,可以使用全局范围对象,而不是使用eval。如果myList
是全局变量,则以下所有内容都是等效的:
myList = [1,2,3];
window.myList = [1,2,3];
window['myList'] = [1,2,3];
2 - 为了获得数组元素,您可以使用字符串中的.split()
方法:
node.innerHTML.split(',')
3 - 如果您想将字符串转换为第一种简单方法,请使用一元+
运算符:
+"3" // is the number 3