it-swarm-tr.com

Bir web sayfasının bir iframe içine mi yoksa doğrudan tarayıcı penceresine mi yüklendiğini nasıl belirleyebilirim?

Bir iframe tabanlı facebook uygulaması yazıyorum. Şimdi normal web sitesi ile facebook'taki tuval sayfasını oluşturmak için aynı html sayfasını kullanmak istiyorum. Sayfanın iframe içine mi yoksa doğrudan tarayıcıya yüklenip yüklenmediğini tespit edip edemediğimi bilmek istiyorum.

518
akshat

Tarayıcılar, aynı Kaynak politikası nedeniyle window.top dosyasına erişimi engelleyebilir. IE hata da oluyor. İşte çalışma kodu:

function inIframe () {
    try {
        return window.self !== window.top;
    } catch (e) {
        return true;
    }
}

top ve self, hem window hem de nesnelerdir (parent ile birlikte), yani pencerenizin en üst pencere olup olmadığını görüyorsunuz.

978
Greg

Üst ile aynı Origin'de bir iframe olduğunda, window.frameElement yöntemi, pencerenin gömülü olduğu öğeyi (örneğin, iframeveya objectname__) döndürür. Aksi takdirde, üst düzey bir bağlamda göz atıyorsanız veya üst ve alt çerçevenin farklı kökenleri varsa, nullolarak değerlendirecektir.

window.frameElement
  ? 'embedded in iframe or object'
  : 'not embedded or cross-Origin'

Bu bir HTML Standardı tüm modern tarayıcılarda temel desteği olan.

78

RoBorg haklı, ancak bir not eklemek istedim.

IE7/IE8’de Microsoft tarayıcılarına Sekmeler eklediğinde, dikkatli olmazsanız JS’nizin zarar görmesine neden olacak bir şey kırdılar.

Bu sayfa düzenini hayal edin:

MainPage.html
  IframedPage1.html   (named "foo")
  IframedPage2.html   (named "bar")
    IframedPage3.html (named "baz")

Şimdi "baz" çerçevesinde bir linke tıklayın (hedef yok, "baz" çerçevesine yükler).

Yüklenen sayfa, special.html olarak adlandırılırsa, "bunun" "bar" adında bir ana kareye sahip olup olmadığını kontrol etmek için JS'yi kullanır (beklenen).

Şimdi, özel.html sayfasının yüklendiğinde ana çerçeveyi (varlığını ve adını kontrol eder) ve "bar" ise, kendisini bar çerçevesine yeniden yüklediğini söyleyelim.

if(window.parent && window.parent.name == 'bar'){
  window.parent.location = self.location;
}

Çok uzak çok iyi. Şimdi böcek geliyor.

Normal gibi orijinal bağlantıya tıklamak ve "baz" çerçevesine special.html sayfasını yüklemek yerine, orta tıklattınız ya da yeni bir Sekmede açmayı seçtiniz.

Bu yeni sekme, üst çerçeve olmadan ( hiç yüklenmediğinde! ) IE, sayfa yükleniyor! çünkü IE ", yeni sekmenin DOES’i bir üst içeriyor ve bu ebeveynin adı" bar "olacak şekilde JavaScript’teki çerçeve yapısının üzerine kopyalıyor.

İyi haber şu ki kontrol etmek:

if(self == top){
  //this returns true!
}

bu yeni sekmede doğru döner ve böylece bu garip durum için test edebilirsiniz.

25
scunliffe

Kabul edilen cevap benim için bir Firefox 6.0 Uzantısı'nın içerik komut dosyasında (Addon-SDK 1.0) işe yaramadı: Firefox, içerik komut dosyasını her birinde: üst düzey pencerede ve tüm iframe'lerde yürütür.

İçerik komut dosyasında aşağıdaki sonuçları alıyorum:

 (window !== window.top) : false 
 (window.self !== window.top) : true

Bu çıktıyla ilgili garip olan şey, kodun bir iframe veya üst düzey pencerede çalıştırılmasından bağımsız olarak her zaman aynı olmasıdır.

Öte yandan, Google Chrome içerik komut dosyamı yalnızca bir kez üst düzey pencerede yürütüyor, bu nedenle yukarıdaki hiçbir işe yaramayacak.

Sonunda iki tarayıcıda da bir içerik komut dosyasında benim için çalıştı.

 console.log(window.frames.length + ':' + parent.frames.length);

İframe'ler olmadan, bu 0:0, bir kare içeren üst düzey bir pencerede 1:1, ve sadece bir belgenin iframe'sinde 0:1 yazdırabilir.

Bu, uzantımın her iki tarayıcıda da iframe olup olmadığını ve ek olarak iframe'lerden birinin içinde çalıştırıldığını Firefox'ta belirlemesini sağlar.

18
magnoz

Bu örneğin eski Web tarayıcıları için nasıl çalıştığından emin değilim, ancak bunu IE, Firefox ve Chrome için kullanıyorum ve yayınlamıyorum:

var iFrameDetection = (window === window.parent) ? false : true;
7
portal TheAnGeLs

Bunu kullanıyorum:

var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
5
mikewolf78

Bu javascript işlevini, bunun nasıl başarılacağına örnek olarak kullanın.

function isNoIframeOrIframeInMyHost() {
// Validation: it must be loaded as the top page, or if it is loaded in an iframe 
// then it must be embedded in my own domain.
// Info: IF top.location.href is not accessible THEN it is embedded in an iframe 
// and the domains are different.
var myresult = true;
try {
    var tophref = top.location.href;
    var tophostname = top.location.hostname.toString();
    var myhref = location.href;
    if (tophref === myhref) {
        myresult = true;
    } else if (tophostname !== "www.yourdomain.com") {
        myresult = false;
    }
} catch (error) { 
  // error is a permission error that top.location.href is not accessible 
  // (which means parent domain <> iframe domain)!
    myresult = false;
}
return myresult;
}
2
Rolf

Aslında window.parent'i kontrol ettim ve benim için çalıştı, ama son zamanlarda pencere döngüsel bir nesne ve her zaman bir ana anahtar var, iframe veya iframe.

Yorumların önerdiği gibi window.parent eserleriyle kıyaslama zor. İframe tam olarak üst sayfa ile aynı web sayfasındaysa bunun işe yarayacağından emin değilim.

window === window.parent;
1
Jabran Saeed

Şimdilik En İyi Eski Tarayıcı Çerçevesi Arası Komut Dosyası

Diğer çözümler benim için işe yaramadı. Bu, tüm tarayıcılarda çalışır:

Tıklama engellemesine karşı savunmanın bir yolu, her sayfaya çerçevelenmemesi gereken bir "çerçeve kırıcı" komut dosyası eklemektir. Aşağıdaki metodoloji, X-Frame-Options-Header'ı desteklemeyen eski tarayıcılarda bile bir web sayfasının çerçevelenmesini önleyecektir.

HEAD element belgesine aşağıdakileri ekleyin:

<style id="antiClickjack">body{display:none !important;}</style>

İlk önce stil öğesinin kendisine bir ID uygulayın:

<script type="text/javascript">
   if (self === top) {
       var antiClickjack = document.getElementById("antiClickjack");
       antiClickjack.parentNode.removeChild(antiClickjack);
   } else {
       top.location = self.location;
   }
</script>

Bu şekilde, her şey HEAD belgesinde olabilir ve API'nizde yalnızca bir yönteme/taglib'e ihtiyacınız vardır.

Referans: https://www.codemagi.com/blog/post/194

1
Albert Olivé

Bir facebook uygulaması bağlamında sorduğunuzdan, ilk istek yapıldığında bunu sunucuda algılamayı düşünebilirsiniz. Facebook, iframe'den çağrılırsa, fb_sig_user anahtarı da dahil olmak üzere bir sürü sorgu veriyi iletir.

Muhtemelen uygulamanızda bu verileri kontrol etmeniz ve kullanmanız gerekeceğinden, oluşturulacak uygun içeriği belirlemek için kullanın.

1
HectorMac

Bu benim için en basit çözüm olmaktan çıktı.

    <p id="demofsdfsdfs"></p>

<script>

if(window.self !== window.top) {

//run this code if in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "in frame";

}else{

//run code if not in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "no frame";
}

</script>
0
Alex Roseland