यह कैसे पहचानें कि यदि किसी वेबपेज को iframe के अंदर या सीधे ब्राउज़र विंडो में लोड किया जा रहा है?


596

मैं एक iframe आधारित facebook ऐप लिख रहा हूं। अब मैं उसी html पेज का उपयोग करना चाहता हूं ताकि सामान्य वेबसाइट के साथ-साथ फेसबुक के भीतर कैनवास पेज भी प्रस्तुत किया जा सके। मैं जानना चाहता हूं कि क्या मैं यह निर्धारित कर सकता हूं कि क्या पेज आईफ्रेम के अंदर लोड किया गया है या सीधे ब्राउज़र में?


2
कुछ अच्छे तरीके (टिप्पणियाँ सहित): tommcfarlin.com/check-if-a-page-is-in-an-iframe
simhumileco

जवाबों:


1106

उसी मूल नीति केwindow.top कारण ब्राउज़र पहुंच को ब्लॉक कर सकता है । IE कीड़े भी लगते हैं। यहाँ काम कर कोड है:

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

topऔर selfदोनों windowऑब्जेक्ट (साथ में parent) हैं, इसलिए आप देख रहे हैं कि क्या आपकी विंडो शीर्ष विंडो है।


4
यह फ़ायरफ़ॉक्स में ठीक काम करने लगता है। क्या यह अन्य ब्राउज़रों में भी काम करता है?
अक्षत

5
एक iframe के साथ एक पृष्ठ के साथ एक iframe के भीतर, अपने बच्चे से iframe का परीक्षण करने के लिए अगर मेरे माता-पिता के iframe को पृष्ठ में
एम्बेड

7
@sglessard यदि बाल पृष्ठ और माता-पिता अलग-अलग डोमेन से हैं, तो फ़ायरफ़ॉक्स उसी मूल नीति (www.w3.org/Security/wiki/Same_Origin_Policy) के लिए शिकायत करेगा और कोड काम नहीं करेगा
गौरांग जूलिया

18
यह मेरे लिए IE 11, 10 और 9 में काम करता है। साथ ही यह FF और ओपेरा के साथ-साथ, Chrome में भी काम करता है। मैं इसके साथ किसी भी मुद्दे पर नहीं चला हूं।
jeremysawesome

4
उन लोगों के लिए जो अभी भी 1995 की तकनीक में नवीनतम रॉकिंग कर रहे हैं , की सामग्री के भीतर से चलने वाले window.self !== window.topरिटर्न , याtrueframe iframe
जेरॉमी फ्रेंच

84

जब मूल के समान मूल पर एक iframe में, window.frameElementविधि तत्व (जैसे iframeया object) जिसमें खिड़की एम्बेडेड है वापस लौटाता है। अन्यथा, यदि कोई शीर्ष-स्तरीय संदर्भ में ब्राउज़ कर रहा है, या यदि माता-पिता और बच्चे के फ्रेम में अलग-अलग मूल हैं, तो यह मूल्यांकन करेगा null

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

यह सभी आधुनिक ब्राउज़रों में मूल समर्थन के साथ एक HTML मानक है।


2
W3C ( WHATWG का कहना है कि इसके बजाय इसे वापस लौटना चाहिए) के frameElementअनुसार, नोट पढ़ने की कोशिश क्रॉस- ऑरिजनल आईफ्रेम में एक सिक्योरिटी अपवाद को फेंक देगी । तो आप इसे एक बयान के अंदर लपेटना चाह सकते हैं । try...catch
ओरियल

5
हो रही nullके अंदर और बाहर कीiframe
OlehZiniak

4
एमडीएन के विवरण में कहा गया है कि "यदि जिस दस्तावेज में यह एम्बेडेड है उसका एक अलग मूल है (जैसे कि एक अलग डोमेन से स्थित है), तो यह शून्य है।"
xeophin

बस यह बताने के लिए कि क्या रिटर्न होना चाहिए:Returns the element (such as <iframe> or <object>) in which the window is embedded, or null if the element is either top-level or is embedded into a document with a different script origin; that is, in cross-origin situations.
Art3mix

26

RoBorg सही है, लेकिन मैं एक साइड नोट जोड़ना चाहता था।

IE7 / IE8 में जब Microsoft ने अपने ब्राउज़र में टैब्स जोड़े तो उन्होंने एक ऐसी चीज़ को तोड़ा जो आपके जेएस के साथ कहर पैदा करेगा अगर आप सावधान नहीं हैं।

इस पृष्ठ लेआउट की कल्पना करें:

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

अब फ्रेम "बाज" में आप एक लिंक पर क्लिक करें (कोई लक्ष्य नहीं है, "बाज" फ्रेम में लोड होता है) यह ठीक काम करता है।

यदि जो पेज लोड हो जाता है, उसे विशेष कहते हैं। html यह जांचने के लिए JS का उपयोग करता है कि "यह" का कोई पेरेंट फ्रेम "बार" है या नहीं, यह सही (अपेक्षित) वापस आएगा।

अब यह कहता है कि विशेष html पृष्ठ जब यह लोड होता है, तो मूल फ्रेम (अस्तित्व और उसके नाम के लिए) की जांच करता है, और यदि यह "बार" है तो यह बार फ्रेम में खुद को फिर से लोड करता है।

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

अब तक सब ठीक है। अब बग आता है।

सामान्य की तरह मूल लिंक पर क्लिक करने और "baz" फ्रेम में special.html पेज को लोड करने के बजाय कहते हैं, आपने इसे बीच में क्लिक किया या इसे नए टैब में खोलने के लिए चुना।

जब वह नया टैब लोड होता है ( बिना किसी पैरेंट फ्रेम के! ) IE पेज लोडिंग के अंतहीन लूप में प्रवेश करेगा! क्योंकि IE "जावास्क्रिप्ट पर फ्रेम संरचना" पर कॉपी करता है जैसे कि नया टैब एक माता-पिता है, और वह माता-पिता "बार" नाम है।

अच्छी खबर यह है कि जाँच:

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

उस नए टैब में यह सही है, और इस प्रकार आप इस विषम स्थिति के लिए परीक्षण कर सकते हैं।


क्या इस बीच बग को ठीक किया गया है? मैं IE8 में इसे पुन: पेश नहीं कर सकता। मुझे हमेशा सही मिलता है window.parent
user123444555621

1
निश्चित नहीं है - मैं IE9 के खिलाफ और फिर से नीचे अपना परीक्षण सूट चलाऊंगा और एक अपडेट पोस्ट करूंगा।
scunliffe

18

स्वीकृत उत्तर मेरे लिए फ़ायरफ़ॉक्स 6.0 एक्सटेंशन (एडऑन-एसडीके 1.0) की सामग्री स्क्रिप्ट के अंदर काम नहीं करता था: फ़ायरफ़ॉक्स प्रत्येक में सामग्री स्क्रिप्ट को निष्पादित करता है: शीर्ष-स्तरीय विंडो और सभी iframes में।

सामग्री स्क्रिप्ट के अंदर मुझे निम्नलिखित परिणाम मिलते हैं:

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

इस आउटपुट के बारे में अजीब बात यह है कि यह हमेशा एक ही है चाहे कोड एक iframe या शीर्ष-स्तरीय विंडो के अंदर चलाया जाए।

दूसरी ओर Google Chrome मेरी सामग्री स्क्रिप्ट को केवल एक बार शीर्ष-स्तरीय विंडो के भीतर निष्पादित करता है, इसलिए उपरोक्त बिल्कुल काम नहीं करेगा।

आखिरकार दोनों ब्राउज़रों में सामग्री स्क्रिप्ट में मेरे लिए क्या काम किया है:

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

इस प्रिंट के आईट्रम के बिना 0:0, एक शीर्ष-स्तरीय विंडो में, जिसमें एक फ्रेम प्रिंट होता है 1:1, और एक डॉक्यूमेंट के एकमात्र आइफ्रेम में यह प्रिंट होता है 0:1

यह मेरे एक्सटेंशन को दोनों ब्राउज़रों में यह निर्धारित करने की अनुमति देता है कि क्या कोई आइफ्रेम मौजूद है, और इसके अलावा फ़ायरफ़ॉक्स में अगर यह आइफ्रेम में से एक के अंदर चलाया जाता है।


1
कोशिश करो document.defaultView.self === document.defaultView.topया window !== window.top। फ़ायरफ़ॉक्स के ऐड-ऑन एसडीके की सामग्री स्क्रिप्ट में, वैश्विक selfऑब्जेक्ट मुख्य स्क्रिप्ट के साथ संवाद करने के लिए उपयोग की जाने वाली वस्तु है।
डब्ल्यू पर रोब डब्ल्यू

13

मुझे यकीन नहीं है कि यह उदाहरण पुराने वेब ब्राउज़र के लिए कैसे काम करता है, लेकिन मैं IE, फ़ायरफ़ॉक्स और क्रोम के लिए इसका उपयोग करता हूं और जारी नहीं करता हूं:

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

6
या बस!(window===window.parent)
कैलक्यूलेटर

11
window! == window.parent
Ivan Leonenko

5

मैं इसका उपयोग कर रहा हूं:

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

आप ऐसा क्यों करते हैं .indexOf("HTMLIFrameElement"):?
ल्यूक

.indexOf ('foobarbaz')> -1 "सबस्ट्रिंग मैच" की जांच करने का एक तरीका है (यानी स्ट्रिंग के भीतर कहीं और 'फ़ोबोर्बाज़' पाया जा सकता है?), लेकिन नियमित अभिव्यक्तियों का उपयोग किए बिना। यह तार्किक रूप से .match (/ foobarbaz /) के बराबर है। यह (:-) का उपयोग ब्राउज़र की एक विस्तृत श्रृंखला पर काम करता है, और अभी भी या तो आदत से बाहर हो सकता है या नियमित अभिव्यक्ति मशीनरी के प्रदर्शन के बारे में आशंकाओं के कारण किया जा सकता है।
चक कोलार

2

इसे पूरा करने के तरीके पर एक उदाहरण के रूप में इस जावास्क्रिप्ट फ़ंक्शन का उपयोग करें।

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

अब के लिए सर्वश्रेष्ठ-लिगेसी ब्राउज़र फ़्रेम ब्रेकिंग स्क्रिप्ट

अन्य समाधानों ने मेरे लिए काम नहीं किया। यह सभी ब्राउज़रों पर काम करता है:

क्लिकजैकिंग से बचाव का एक तरीका यह है कि प्रत्येक पृष्ठ में एक "फ्रेम-ब्रेकर" स्क्रिप्ट को शामिल किया जाए जिसे फंसाया नहीं जाना चाहिए। निम्नलिखित कार्यप्रणाली वेब पेज को विरासत के ब्राउज़र में भी फ़्रेम होने से रोकेगी, जो कि X- फ्रेम-ऑप्शंस-हैडर का समर्थन नहीं करता है।

दस्तावेज़ में मुख्य तत्व, निम्नलिखित जोड़ें:

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

सबसे पहले शैली तत्व में एक आईडी लागू करें:

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

इस तरह, सब कुछ दस्तावेज़ हेड में हो सकता है और आपको अपने एपीआई में केवल एक विधि / टैगलिब की आवश्यकता है।

संदर्भ: https://www.codemagi.com/blog/post/194


1
फ़्रेमिंग केवल खतरा नहीं है, आपत्ति करने के बारे में क्या है (एचटीएमएल 5 ऑब्जेक्ट टैग का उपयोग करने का अर्थ है जो आईफ्रेम टैग को बदल देता है) .. मुझे लगता है कि यह उस के खिलाफ काम नहीं करेगा ..
रेमंड निजलैंड


1

चूंकि आप एक फेसबुक ऐप के संदर्भ में पूछ रहे हैं, आप प्रारंभिक अनुरोध किए जाने पर सर्वर पर इसका पता लगाने पर विचार कर सकते हैं। अगर यह iframe से कॉल किया जाता है, तो फेसबुक fb_sig_user कुंजी सहित डेटा को नष्ट करने के एक समूह के साथ गुजर जाएगा।

चूंकि आपको संभवतः अपने ऐप में वैसे भी इस डेटा की जांच और उपयोग करने की आवश्यकता है, इसलिए रेंडर करने के लिए उपयुक्त संदर्भ निर्धारित करने के लिए इसका उपयोग करें।


1

मैं वास्तव में window.parent की जांच करता था और यह मेरे लिए काम करता था, लेकिन हाल ही में खिड़की एक चक्रीय वस्तु है और इसमें हमेशा एक पैरेंट की, iframe या कोई iframe होता है।

जैसा कि टिप्पणियों का सुझाव है कि window.parent कार्यों के साथ तुलना करना कठिन है। निश्चित नहीं है कि यह काम करेगा अगर iframe माता-पिता के समान वेबपेज है।

window === window.parent;

क्रोम में मुख्य विंडो संदर्भ window.parent === windowसही है। तो आपका जवाब गलत है। और इस मजबूरी का उपयोग चेक के लिए किया जा सकता है (कम से कम क्रोम में, दूसरे ब्राउज़र में इसका परीक्षण नहीं किया गया)।
मार्कोसयनअर्टूर

IFrame के संदर्भ में काम नहीं करता है, लेकिन `if (window === window.parent) {` करता है। मैं आपको नीचे चिह्नित नहीं कर रहा हूं क्योंकि मुझे नहीं पता कि यह काम क्यों नहीं करता है
www-0av-Com

-1

यह कोड का एक प्राचीन टुकड़ा है जिसका मैंने कुछ बार उपयोग किया है:

if (parent.location.href == self.location.href) {
    window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}

(parent.location == self.location)
एनेको

@piotr_cz, यह तभी काम करता है जब समान-मूल नीति एक्सेस करने की अनुमति देती है parent.location। अन्यथा एक अपवाद फेंक दिया जाता है
डैन

-1

यदि आप जानना चाहते हैं कि क्या उपयोगकर्ता साइन अप किए गए अनुरोध के लिए फेसबुक पेज टैब या कैनवास चेक से आपके ऐप को एक्सेस कर रहा है। यदि आपको यह नहीं मिलता है, तो शायद उपयोगकर्ता फेसबुक से एक्सेस नहीं कर रहा है। यह सुनिश्चित करने के लिए कि हस्ताक्षर किए गए_रेक्वेस्ट फ़ील्ड संरचना और फ़ील्ड सामग्री की पुष्टि करें।

Php-sdk के साथ आप इस तरह हस्ताक्षरित अनुरोध प्राप्त कर सकते हैं:

$signed_request = $facebook->getSignedRequest();

आप यहाँ हस्ताक्षरित अनुरोध के बारे में अधिक पढ़ सकते हैं:

https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/

और यहाँ:

https://developers.facebook.com/docs/reference/login/signed-request/


-1

यह मेरे लिए सबसे सरल उपाय रहा।

    <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>

-4
if (window.frames.length != parent.frames.length) { page loaded in iframe }

लेकिन केवल अगर iframes की संख्या आपके पेज और पेज में भिन्न होती है जो आपको iframe में लोड कर रहे हैं। इस कोड के परिणाम की 100% गारंटी के लिए अपने पेज में कोई iframe न बनाएं


यह निर्धारित करने के लिए एक बहुत ही सुंदर समाधान नहीं है कि खिड़की एक iframe के अंदर है या नहीं, और कोई गारंटी नहीं है कि आप माता-पिता से पढ़ने में सक्षम होंगे या तो।
पर्सी

-4

प्रत्येक पृष्ठ में इस जावास्क्रिप्ट को लिखें

if (self == top)
  { window.location = "Home.aspx"; }

फिर यह अपने आप होम पेज पर रीडायरेक्ट हो जाएगा।


4
जब आप फ़्रेम नहीं करेंगे तो आपका रीडायरेक्ट काम करेगा। इसलिए मैं आपकी साइट पर नेविगेट नहीं कर पाऊंगा। दूसरे, मूल पृष्ठ से पुनर्निर्देशन को रोकने के लिए तकनीक मौजूद है।
मारियस बाल्कीटिस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.