如何在我的代码中的其他地方定义的函数被拒绝或在某些对象被分配给对象时被限制访问?
简短示例
var func = function() {
console.log(window.screenX); // <-- this should work
document.createElement("div"); // <-- this should fail (ideally in
// some graceful way)
};
var makeObj = function(pFunc) {
var window = {
"screenX": window.screenX
};
var document = null;
var rObj = {};
rObj.func = pFunc;
return rObj;
};
var obj = makeObj(func);
obj.func(); // <-- want it to have no access to document and
// limited access to window
func
由特权用户定义为一种插件,但我想限制他们可以做的事情,例如不创建新元素但仍然能够访问他们需要的某些变量和函数(例如{ {1}})
答案 0 :(得分:0)
我确信有很多可能的答案,我的回答是使用Function-constructor,以便window
和document
在本地定义的范围内本地定义功能。这非常重要,因为您不希望全局覆盖这两个对象。
但是让我们来回答这个问题。在makeObj
中func
中的所有允许对象都使用new Function
- 构造函数的第一个和第二个参数定义。
第三个参数用于创建“匿名”函数,该函数包含对这些允许对象的某些赋值。这些分配是使用serializeFakeObject
在本地创建的。
换句话说,第一个和第二个参数new Function
将成为参数(标题或签名),而第三个参数将成为“匿名”函数的主体。
请注意,此“匿名”功能是动态创建的,之后如下所示:
function anonymous(window,document) {
// overwrites allowed objects
window = {"screenX":-8};
document = {};
document.createElement = function (){ throw Error("document.createElement is not allowed"); };
// this function must take assignments above
// no chance to use the globally defined objects window or document
return function (){
console.log(window);
console.log(document.createElement());
}();
}
此匿名函数在makeObj
内动态创建,之后通过调用obj.func()
执行。
让我们把所有人放在一起:
var func = function (){
console.log(window); // has just got screenX
console.log(document.createElement()); // throws an error "document.createElement is not allowed"
};
var makeObj = function(pFunc) {
var serializeFakeObject = function(name,obj){
var serializedObject = "";
// when its a property of type function then omit JSON.stringify otherwise it gets undefined
if(obj.__proto__.constructor === Function)serializedObject = obj;
else serializedObject = JSON.stringify(obj);
return name + ' = ' + serializedObject + ';';
};
var fakeWindow = serializeFakeObject("window", { "screenX": window.screenX });
var fakeDocument = serializeFakeObject("document", {});
// create property createElement of document that should fail in a graceful way
var fakeDocumentProperty = serializeFakeObject("document.createElement", function (){ throw Error("document.createElement is not allowed"); });
// if you like you can add more properties here....
var concatFakeObjects = fakeWindow+fakeDocument+fakeDocumentProperty;
var rObj = {};
// the line below creates the "anonymous" function described above
rObj.func = new Function('window', 'document', concatFakeObjects +'return '+pFunc+'();');
return rObj;
};
var obj = makeObj(func);
console.log(obj.func());