2011-12-08 13 views
17

更新:これは未回答ですので、私は少し質問を変えています。ディーンのブログの記事のコメントは、この技術がSafariでは動作しないことを示しています。今「iframe sandbox」技術は安全ですか?

私の質問は:最近のブラウザで仕事*の下に記載された技術ではない、特に誰かが、それはSafariで動作するかどうかを確認することができますか?ここで

は、より最近のblog postです。これは、1つの点で言う:

サンドボックス原住民... ...サファリ2.0+

含むブラウザの様々な、でサポートされている...しかし、後のiframe技術」であると述べていますSafariを除くすべての主要なブラウザでサポートされています」と偽装されたのは、偽装されたコンストラクタと奇妙なことをやっていることで、ちょっとハッキリしているようです。__proto__

私はほとんどそれが難しい二つの異なるウィンドウが実際には同じ、たとえば、のObject.prototypeを共有することができると信じることを見つけます。クロスドメインiframeはどうなりますか?あるフレームでプロトタイプを変更した場合、他のフレームのプロトタイプは変更されますか?これは明らかなセキュリティ上の懸念のようです。誰かがこの状況についていくつかの光を当ててください。

*「仕事」とは、My.Object != Objectを意味するので、プロトタイプは1つのウィンドウで変更され、他のウィンドウに影響を与えることはありません。


オリジナルポスト

私は、これは前に頼まれましたが、私は心の中で具体的な解決策を持っている、と私はこのタイプのソリューションが議論されているかどうかを知りたいの前に、どこ私は知っていますそれがいかに信頼性が高く、受け入れられているかを学ぶかもしれない。

実際に型自体を混乱させることなくネイティブ型を拡張する方法です。Array.prototypeを変更するだけでいいわけではありません(他のコードは配列でfor..inを使用している可能性があります)。いくつかの関数を組み込んだネイティブ配列を返す偽のコンストラクタを作成すると、良い解決策のようには見えません。実際にネイティブオブジェクトを拡張する方が良いようです。しかし、ネイティブ関数を呼び出そうとすると "push is generic"のようなエラーが発生するため、通常のjavascriptダミー関数prototype switcharooスタイル拡張をnative型で行うことはできません。

だから、私が考えているソリューションは、次のように機能します。そのウィンドウでネイティブコンストラクタのプロトタイプに機能を追加し、別のウィンドウを作成し、あなたのプログラムでこれらのコンストラクタを使用します。

この例ではalert機能付きMy.Stringeachとしての機能を有するMy.ArrayStringとしてArray延びています。

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; 

    }()); 

繰り返しますが、私の質問は、このアプローチは、私が別のグローバルスコープを取得するクリーンな方法があるかどうかを知りたいなど、私はより多くの情報を見つけることができる場所、と呼ばれるもの、以前に議論されているかどうかでありますiframeを使用せずに、または可能であれば、これは特定のJavaScriptエンジンで何らかの理由で失敗するか、誰かがそれが特に悪い考えであると思った場合には失敗します。


アップデート:私は、人々がHTML5のiframe sandbox属性と混同しないように、iframeのサンドボックスこの種のものを呼び出していると思います。

関連:

http://dean.edwards.name/weblog/2006/11/hooray/

http://webreflection.blogspot.com/2008/03/javascript-arrayobject.html

+0

は、アイフレームの合法的な使用である... – hugomg

+0

missingno、現在使用して何を知っていますこのテクニックは?それは奇妙な結果の束を持っていると私はそれが使用されている場合、どこかにメーリングリストの議論がなければならないと想像している –

+3

私は[プレゼンテーション](http://www.slideshare.net/benvinegar/modern-iframe-programming) -8281214)をDisqusの男から入手しました。彼らは基本的にどこにでもコードを埋め込むことができる必要があるので、この種のトリックを使用します。 – hugomg

答えて

6

私はこのページをさまざまなブラウザ(Safari、Opera、IE7-9、Chrome、Firefox)で実行していますが、firefoxではすべての結果が一貫していますが、試作品はサンドボックス化されていますが、ファイアフォックスでiframeプロトタイプはすぐに拡張されません。とにかくそれを増やすつもりでないなら、これは問題ではありません。より多くのブラウザでテストしてみてください。

これは実際にどのような不具合もテストしていないことに注意してください(My.Array().sliceは、ブラウザに応じてwindowのメインの配列を返します)。だから私はそれがかなり危険だと言うでしょう。

とにかく残酷で、実際の利益を得るにはあまりにも多くの作業が必要です。この技術は、ほとんどの場合、*その後、それらを追加するためにそれらの余分な方法を取り除く*を取得するために使用されているが、クリーンウィンドウオブジェクトを取得

<!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> 
+1

これを正しくマークします。結局のところ、iframeサンドボックスのことをやっていないことに決めました。理由はさまざまです。 –

1

あなたが別のドメインからロードされたコンテンツを持つ2つの異なるフレームを持っている場合は、何も現代のブラウザは明らかなセキュリティのために、それらの間のJavaScriptのレベル上の任意の相互作用を可能にしません理由。もちろん、テストをセットアップして自分のために何が起こるかを確認するのが最善の策ですが、私はあなたが何を記述しているかは、ほとんどのブラウザで安全でなければならないと確信しています。

+0

ええ、私はマックを持っていません。本当に私は誰かが私のためにそれをテストする必要があります。また、別のサブドメインでiframeを起動し、その後document.domainを変更することで偽装できるかどうかも疑問です。 –

+0

ああ、私はMacを持っていません。 IE、FireFox、Chromeで試してみるといいでしょう。それが3つ全てを通過すれば、あなたは良いと言えるでしょう。後でSafariでそれをテストする人がいるかもしれませんが、私はそれがあなたのために優先されるべきではないと思います。もちろん、あなたが本当にしたいのであれば、VirtualBoxでMacOSインスタンスをいつでも設定することができます.... –