在我的网络应用程序中,我想接受任意 JavaScript 对象作为 GET 参数。所以我需要以location.search
类似于 的方式进行解析eval
,但我只想创建自包含对象(对象文字、数组、正则表达式和可能的受限访问函数):
var search =
location.search ?
decodeURIComponent(location.search).substring(1).split('&') :
['boo=alert(1)', 'filter={a: /^t/, b: function(i){return i+1;}}']
;
var params = {};
for (var i = 0, temp; i < search.length; i++){
temp = search[i].split('=');
temp = temp[1] ? temp : [temp[0], null];
params[temp[0]] = saferEval(temp[1]);
};
console.log(params);
我想出了一个saferEval
阻止访问全局变量的函数版本,但它不会阻止访问内置函数,例如alert()
:
var saferEval = function(s) {
'use strict';
var deteleGlobals =
'var ' +
Object.getOwnPropertyNames(window)
.join(',')
.replace(/(?:eval|chrome:[^,]*),/g, '') +
';'
;
try {
return eval(deteleGlobals + '(' + s + ');') || s;
} catch(e) {
return s;
};
};
请参阅我的jsFiddle -alert(1)
代码已执行。
请注意,top.location
jsFiddle 脚本无法访问,如果您想使用实际的查询参数(如?filter={a: /%5Cd+/g}
.
我会使用 JSON,但我需要在数组和对象内的任意位置使用正则表达式。我不会将这些对象中的任何一个发送回服务器,因此使用eval
它不应该对安全性造成太大损害......
如何在不授予它访问全局命名空间和内置函数的权限的情况下将字符串(编码 JavaScript 对象)转换为对象?
更新 - 只有有用的“任意”对象原来是正则表达式文字......