Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/406.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是",;iframe沙箱“;技术安全?_Javascript_Iframe_Constructor_Safari - Fatal编程技术网

Javascript 是",;iframe沙箱“;技术安全?

Javascript 是",;iframe沙箱“;技术安全?,javascript,iframe,constructor,safari,Javascript,Iframe,Constructor,Safari,更新:由于这个问题没有答案,我稍微改变一下问题。下面链接的Dean博客帖子上的评论表明,这种技术在Safari中不起作用 我现在的问题是:下面描述的技术在现代浏览器中有效吗?特别是有人能确认它在Safari中是否有效吗 这是最近的一个例子。它在某一点上说: 沙盒土著。。。在多种浏览器中都受支持,包括。。。Safari 2.0+ …但后来他说iframe技术“除Safari外,所有主流浏览器都支持”,他展示的回退方法包括使用伪造的构造函数和似乎有点黑客的\uuuuuuuuuuuuuuuuu做一些奇

更新:由于这个问题没有答案,我稍微改变一下问题。下面链接的Dean博客帖子上的评论表明,这种技术在Safari中不起作用

我现在的问题是:下面描述的技术在现代浏览器中有效吗?特别是有人能确认它在Safari中是否有效吗

这是最近的一个例子。它在某一点上说:

沙盒土著。。。在多种浏览器中都受支持,包括。。。Safari 2.0+

…但后来他说iframe技术“除Safari外,所有主流浏览器都支持”,他展示的回退方法包括使用伪造的构造函数和似乎有点黑客的
\uuuuuuuuuuuuuuuuu
做一些奇怪的事情

我几乎很难相信两个不同的窗口实际上可以共享同一个,比如Object.prototype。跨域iframe会发生什么?如果我在一个框架中修改原型,那么在另一个框架中的原型会被修改吗?这似乎是一个明显的安全问题。请有人解释一下这种情况

*我所说的“工作”是指
My.Object!=对象,因此可以在一个窗口中修改原型,而不会影响另一个窗口


原创帖子

我知道以前有人问过这个问题,但我心里有一个具体的解决方案,我想知道以前是否讨论过这种类型的解决方案,以及在哪里我可以了解到它是多么可靠和被广泛接受

问题是如何在javascript中扩展本机类型而不实际干扰类型本身,因此仅仅更改Array.prototype是不好的(可能其他代码正在使用数组中的..)。创建一个假构造函数返回一个带有附加函数的本机数组似乎也不是一个好的解决方案,实际上扩展本机对象似乎更好。但是,您也不能使用本机类型执行普通javascript伪函数原型switcharoo样式的扩展,因为当您尝试调用本机函数时,会出现诸如“push不是泛型”之类的错误

因此,我想到的解决方案是这样的:创建另一个窗口,将功能添加到该窗口中本机构造函数的原型中,并在程序中使用这些构造函数

此示例将
Array
扩展为
My.Array
,使用
each
函数,将
String
扩展为
My.String
,使用
alert
函数

    var My = (function(){

      // create an iframe to get a separate global scope
      var iframe = document.createElement('iframe');
      iframe.style.height = '0px';
      iframe.style.width = '0px';
      iframe.style.border = 'none';
      iframe.style.position = 'absolute';
      iframe.style.left = '-99999px';
      document.documentElement.appendChild(iframe);
      var My = iframe.contentWindow;

      My.String.prototype.alert = function(){
        alert(this);
      }

      My.Array.prototype.each = function(callback){
        for (var i=0, l=this.length; i<l; i++) {
          callback(this[i], i);
        }
      }

      return My;

    }());
var My=(函数(){
//创建iframe以获得单独的全局范围
var iframe=document.createElement('iframe');
iframe.style.height='0px';
iframe.style.width='0px';
iframe.style.border='none';
iframe.style.position='绝对';
iframe.style.left='-9999px';
document.documentElement.appendChild(iframe);
var My=iframe.contentWindow;
My.String.prototype.alert=函数(){
警惕(这个);
}
My.Array.prototype.each=函数(回调){

对于(var i=0,l=this.length;i如果您有两个不同的框架,其中包含从不同域加载的内容,那么出于明显的安全原因,现代浏览器将不允许它们之间在JavaScript级别上进行任何交互。当然,您最好设置一个测试,看看自己会发生什么,但我非常确定您描述的是什么ribing在大多数浏览器上都应该是安全的。

我在各种浏览器(Safari、Opera、IE7-9、Chrome、Firefox)上运行了此页面在firefox中,原型是沙盒的,所以这很好,但是在firefox中,由于某种原因,第二次测试失败了。iframe原型没有立即增强。但是,如果你不打算增强它,这并不重要。你可以尝试在更多的浏览器中运行它进行测试

请注意,这并没有真正测试任何怪癖,例如(
My.Array().slice
将返回主
窗口
数组,具体取决于浏览器…),可能还有更多怪癖。因此我认为这是非常不安全的

不管怎么说,这是一种过度的杀伤力,似乎做了太多的工作却没有真正的收获

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript">
(function(){
    var ifr = document.createElement("iframe"),
        callbacks = [],
        hasReadyState = "readyState" in ifr;

    ifr.style.display = "none";


    document.body.appendChild(ifr);
    ifrDoc = ifr.contentWindow.document;
    ifrDoc.open();
    ifrDoc.write( "<!DOCTYPE html><html><head></head><body>"+"<"+"script"+">var w = this;"+"</"+"script"+">"+"</body></html>");
    ifrDoc.close();

    if( hasReadyState ) {

        ifr.onreadystatechange = function(){
            if( this.readyState === "complete" ) {
                fireCallbacks();
            }
        };

    }

    function fireCallbacks(){
        var i, l = callbacks.length;
        window.My = ifr.contentWindow.w;

        for( i = 0; i < l; ++i ) {
            callbacks[i]();
        }

        callbacks.length = 0;


    }

    function checkReady(){

        if( hasReadyState && ifr.readyState === "complete" ) {
        fireCallbacks();
        }
        else if( !hasReadyState ) {
        fireCallbacks();
        }
    }

    window.MyReady = function(fn){
        if( typeof fn == "function" ) {
            callbacks.push( fn );
        }
    };


window.onload = checkReady; //Change this to DOMReady or whatever
})()


MyReady( function(){

    My.Object.prototype.test = "hi";

    var a = new My.Object(),
        b = new Object();

    console.log( Math.random(), My.Object !== Object && b.test !== "hi", a.test === "hi" );

});
</script>

</body>
</html>

(功能(){
var ifr=document.createElement(“iframe”),
回调=[],
ifr中的hasReadyState=“readyState”;
ifr.style.display=“无”;
文件.正文.附件(ifr);
ifrDoc=ifr.contentWindow.document;
ifrDoc.open();
write(“+”var w=this;“+”+);
ifrDoc.close();
如果(hasReadyState){
ifr.onreadystatechange=函数(){
如果(this.readyState==“完成”){
fireCallbacks();
}
};
}
函数fireCallbacks(){
var i,l=回调.length;
window.My=ifr.contentWindow.w;
对于(i=0;i
获得一个干净的窗口对象是iFrame的合法用途,尽管这种技术通常用于去除那些额外的方法,然后添加它们……不,你知道目前有什么使用这种技术的吗?它有一系列奇怪的后果,我想如果它是我记得我读过一篇来自Discus的文章。他们使用这种技巧,因为他们需要能够嵌入他们的代码