Javascript高级闭包

Javascript高级闭包,javascript,security,function,code-injection,Javascript,Security,Function,Code Injection,我目前正在从事一个项目,该项目允许您在文本区域中键入Javascript,并将其运行。有很多后台代码监视页面并将数据发送到服务器。所有这些都是在一个私有函数中,因此不能简单地使用控制台闯入。唯一的问题是,在textarea键入的代码在包含服务器函数的私有函数中进行计算,从而使其能够访问站点的内部。如何将其隔离并使其在私有函数之外?一个例子如下: <script> var x = 2; (function(){ var x = 10; var elem = docum

我目前正在从事一个项目,该项目允许您在文本区域中键入Javascript,并将其运行。有很多后台代码监视页面并将数据发送到服务器。所有这些都是在一个私有函数中,因此不能简单地使用控制台闯入。唯一的问题是,在textarea键入的代码在包含服务器函数的私有函数中进行计算,从而使其能够访问站点的内部。如何将其隔离并使其在私有函数之外?一个例子如下:

<script>

var x = 2;
(function(){
    var x = 10;
    var elem = document.createElement('button');
    elem.addEventListener('click',function(){
        alert(x);
    });
    document.body.appendChild(elem);
})();

</script>

var x=2;
(功能(){
var x=10;
var elem=document.createElement('button');
元素addEventListener('click',函数(){
警报(x);
});
文件.正文.附件(elem);
})();
在本例中,当按下按钮时,我希望x返回2而不是10。从而迫使它像在全局范围内一样运行

编辑 我曾尝试将函数绑定到窗口,该窗口似乎走上了正确的道路,但没有达到我想要的效果

<script>

var x = 2;
(function(){
    var x = 10;
    var elem = document.createElement('button');
    elem.addEventListener('click',(function(){
        alert(x);
    }).bind(window));
    document.body.appendChild(elem);
})();

</script>

var x=2;
(功能(){
var x=10;
var elem=document.createElement('button');
元素addEventListener('单击',(函数()){
警报(x);
}).绑定(窗口);
文件.正文.附件(elem);
})();

我还尝试将窗口应用于该函数,但遗憾的是,这也不起作用。

在您编辑的中,版本更改警报(x)到警报(.x)。
它解决了你的问题吗?

事实证明,答案比我想象的要简单得多。在全局范围内但在封闭函数之外的函数可以被任何函数调用,但它只能访问全局范围内的变量。因此,下面的示例非常有效

<script>

var run = function(){alert(x);};
var x = 2;
(function(){
    var x = 10;
    var elem = document.createElement('button');
    elem.addEventListener('click',run);
    document.body.appendChild(elem);
})();

</script>

var run=function(){alert(x);};
var x=2;
(功能(){
var x=10;
var elem=document.createElement('button');
元素addEventListener(“单击”,运行);
文件.正文.附件(elem);
})();

“所有这些都在一个私有函数中,因此不能简单地使用控制台闯入。”没错,就像人们不能用您在脚本中提供的数据伪造XHR请求一样。安全性和验证与前端无关,您必须在后端进行验证。嗯,但它迫使人们实际阅读和理解脚本,而不是在控制台中处理变量,这将有点困难,因为我使用的是comet通道,通道是创建的,并且仅限于私有函数。在页面中创建一次频道后,我认为不允许复制该频道。因此,仅通过控制台使用频道变得更加困难。您无法访问在闭包外部声明的第一个
x
,因为它被闭包内部声明的
x
遮挡。如果从第三行中删除关键字
var
,您将可以访问该外部变量,但随后您将在同一行中覆盖其值(现在仅为
x=10
),这也不是您想要的。这是通常与使用全局变量相关的许多问题之一。如果在全局范围内,可以使用
window.x
。不知道comet是否会影响这一点。这确实有效,但是因为用户提供的是代码而不是我,所以我不能确切地要求他们在每个变量前面键入此代码。您可以看到,其目的是从用户提交的代码中隐藏第二个x。