我可以限制字符串生成函數(使用函數構造函數)訪問父/全局作用域嗎?在Javascript中使用函數()創建沙箱
例如:下面的代碼按原樣打印false,因爲該函數正在窗口中存儲/修改變量a。
window.a = 4;
Function("a=3;")()
console.log(a === 4);
我能限制訪問窗口/父範圍,並使其打印出「真」?
我可以限制字符串生成函數(使用函數構造函數)訪問父/全局作用域嗎?在Javascript中使用函數()創建沙箱
例如:下面的代碼按原樣打印false,因爲該函數正在窗口中存儲/修改變量a。
window.a = 4;
Function("a=3;")()
console.log(a === 4);
我能限制訪問窗口/父範圍,並使其打印出「真」?
我不這麼認爲。使他們的影子他們,你能說出你想要的參數,以保護全局:
window.a = 4;
Function("a", "a=3;")()
console.log(a === 4);
但功能將不得不進入全球不管你嘗試......這就是爲什麼它被稱爲全球。
根據你想要做的事情,還有其他的解決方法,比如網絡工作者......並且一如既往,hidden iframe hacks。
@ Esailija的回答是對的。另外,我建議首先限制你必須保護的全局變量的數量。放任何東西,你通常會放在全局命名空間中的APP
範圍,你控制:
var APP = (function() {
return {
a: 4
};
}());
有沒有辦法完全限制訪問全球範圍內,但至少這種方式,你只需要保護一個對象:APP
。
這是一個額外的想法,與Esailija的建議一起可能非常強大(請參閱關於他的討論的評論)。
您可以創建虛擬iframe並使用其Function
函數。使用它創建的函數默認情況下只能訪問iframe的範圍,儘管它仍然可以跳出它。幸運的是,通過Esailija的建議,很容易防止這種情況發生。
我能想象的功能是這樣的:
function sandboxed(code) {
var frame = document.createElement('iframe');
document.body.appendChild(frame);
var F = frame.contentWindow.Function,
args = Object.keys(frame.contentWindow).join();
document.body.removeChild(frame);
return F(args, code)();
}
可選方案,您可能要在前面加上'use strict';
的代碼。
這至少在Chrome中起作用。
(function() {
var frame = document.createElement('iframe');
document.body.appendChild(frame);
var same = window === frame.contentWindow.Function('return window;')();
alert(same ? ':(' : ':)');
document.body.removeChild(frame);
}());
非常有創意:D + 1我得到':)'除IE8之外,它拋出一個'不支持屬性或方法函數' – Esailija 2012-08-08 17:54:50
@Esailija:謝謝測試(我沒有IE)。也許iframe的源代碼必須在IE中明確設置('frame.src ='about:blank''應該這樣做),或者該屬性的命名方式不同(不是'contentWindow')。如果你必須設置源代碼,也許你必須等待'load'事件才能訪問窗口,但是當然''sandboxed''接受回調的結果是沒有問題的:) – 2012-08-08 18:37:05
是的,設置'frame .src'工程。 – Esailija 2012-08-08 18:45:50
嗯,你可以定義'window'和'document'作爲參數,以防止直接訪問:無論是創建這樣的函數可以訪問iframe的全局範圍或頁面的全局範圍可以很容易地測他們(如你已經說過的),然後在代碼中加上''strict strict';'以防止全局變量的隱式定義。這可能會起作用。但是,只要不通過參數「遮蔽」它們,當然它並不妨礙對現有全局變量的訪問。也許可以迭代所有'window'屬性並自動創建參數列表。 – 2012-08-08 17:17:31
@FelixKling聽起來不錯,我會嘗試一些黑客,看看我是否仍然可以訪問全球 – Esailija 2012-08-08 17:18:12
@FelixKling這裏是我目前的一個,可以工作,如果你影「功能」http://jsfiddle.net/dFmyd/ – Esailija 2012-08-08 17:21:15