Γράφω ένα iframe που βασίζεται facebook app. Τώρα θέλω να χρησιμοποιήσω την ίδια σελίδα html για να καταστήσει την κανονική ιστοσελίδα, καθώς και τη σελίδα καμβά μέσα στο facebook. Θέλω να ξέρω αν μπορώ να καθοριστεί αν η σελίδα έχει τοποθετηθεί στο εσωτερικό του iframe ή απευθείας στο πρόγραμμα περιήγησης;
Πώς να προσδιορίσει αν μια ιστοσελίδα φορτώνεται μέσα σε ένα iframe ή απευθείας στο παράθυρο του προγράμματος περιήγησης;
Τα προγράμματα περιήγησης μπορεί να εμποδίσει την πρόσβαση σε window.topοφείλεται σε ίδια πολιτική προέλευση . IE σφάλματα λαμβάνουν επίσης μέρος. Εδώ είναι ο κώδικας εργασίας:
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
topκαι selfείναι και οι δύο windowαντικείμενα (μαζί με parent), έτσι ώστε να βλέπετε αν το παράθυρό σας είναι το κορυφαίο παράθυρο.
RoBorg είναι σωστό, αλλά ήθελα να προσθέσω μια πλευρά σημείωση.
Σε IE7 / IE8 όταν η Microsoft πρόσθεσε καρτέλες στον browser τους, έσπασε ένα πράγμα που θα προκαλέσει τον όλεθρο με JS σας, αν δεν είστε προσεκτικοί.
Φανταστείτε αυτή τη διάταξη σελίδας:
MainPage.html
IframedPage1.html (named "foo")
IframedPage2.html (named "bar")
IframedPage3.html (named "baz")
Τώρα στο πλαίσιο «baz» κάνετε κλικ σε ένα σύνδεσμο (δεν στόχο, τα φορτία στο πλαίσιο «Baz») δουλεύει μια χαρά.
Αν η σελίδα που φορτώνεται, ας το ονομάσουμε special.html, χρησιμοποιεί JS για να ελέγξετε αν «αυτό» έχει ένα γονέα πλαίσιο που ονομάζεται «γραμμή» θα επιστρέψει αλήθεια (αναμενόμενο).
Τώρα ας πούμε ότι η σελίδα special.html όταν φορτώνει, ελέγχει τη μητρική πλαισίου (για την ύπαρξη και το όνομά του, και αν είναι «γραμμή» είναι η ίδια φορτώνει στο πλαίσιο bar. Π.χ.
if(window.parent && window.parent.name == 'bar'){
window.parent.location = self.location;
}
Μέχρι εδώ καλά. Τώρα έρχεται το σφάλμα.
Ας πούμε αντί να κάνετε κλικ στο αρχικό σύνδεσμο σαν κανονικό, και φόρτωση της σελίδας special.html στο «Baz» καρέ, μπορείτε να το μεσαίο κλικ ή επέλεξαν να το ανοίξετε σε μια νέα καρτέλα.
Κατά ότι τα νέα φορτία καρτέλα ( χωρίς μητρική πλαίσια καθόλου! ) IE θα τεθεί ένα ατελείωτο βρόχο της φόρτωσης της σελίδας! επειδή IE «αντίτυπα πάνω από» τη δομή του πλαισίου σε JavaScript, έτσι ώστε η νέα καρτέλα έχει ένα γονέα, και ο γονέας έχει το όνομα «γραμμή».
Τα καλά νέα είναι ότι ο έλεγχος:
if(self == top){
//this returns true!
}
στη νέα καρτέλα έχει επιστρέψει αλήθεια, και έτσι μπορείτε να δοκιμάσετε για αυτό το περίεργο όρο.
Από τη στιγμή που ζητάμε στο πλαίσιο της εφαρμογής facebook, ίσως να θέλετε να εξετάσει την ανίχνευση αυτή στο διακομιστή, όταν η αρχική υποβολή της αίτησης. Facebook θα περάσετε μαζί μια δέσμη των QueryString δεδομένων, συμπεριλαμβανομένων κλειδί fb_sig_user εάν καλείται από ένα iframe.
Από τότε μάλλον πρέπει να ελέγξει και να χρησιμοποιήσει αυτά τα δεδομένα ούτως ή άλλως στην εφαρμογή σας, χρησιμοποιήστε το για να καθορίσει την το κατάλληλο πλαίσιο για να καταστήσει.
Χρησιμοποιήστε αυτή τη λειτουργία javascript ως παράδειγμα για το πώς θα επιτευχθεί αυτό.
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;
}
Η αποδεκτή απάντηση δεν λειτούργησε για μένα μέσα στο σενάριο περιεχομένου του Firefox 6.0 Επέκταση (Addon-SDK 1.0): Firefox εκτελεί το σενάριο περιεχομένου σε κάθε ένα: το παράθυρο ανώτατου επιπέδου και σε όλα τα iframes.
Μέσα από το σενάριο περιεχομένου πάρω τα ακόλουθα αποτελέσματα:
(window !== window.top) : false
(window.self !== window.top) : true
Το περίεργο πράγμα σχετικά με αυτό το προϊόν είναι ότι είναι πάντα το ίδιο, ανεξάρτητα αν ο κώδικας εκτελείται μέσα σε ένα iframe ή στο παράθυρο ανώτατου επιπέδου.
Από την άλλη πλευρά, το Google Chrome φαίνεται να εκτελέσει το σενάριο περιεχομένου μου μόνο μια φορά μέσα στο παράθυρο ανώτατου επιπέδου, οπότε τα παραπάνω δεν θα λειτουργούν καθόλου.
Αυτό που τελικά λειτούργησε για μένα σε ένα σενάριο περιεχομένου και στα δύο προγράμματα περιήγησης είναι το εξής:
console.log(window.frames.length + ':' + parent.frames.length);
Χωρίς iframes αυτό εκτυπώσεις 0:0, σε ένα παράθυρο ανώτατου επιπέδου που περιέχει ένα πλαίσιο εκτυπώνει 1:1, και στο μοναδικό iframe ενός εγγράφου εκτυπώνεται 0:1.
Αυτό επιτρέπει την επέκταση μου να καθορίσει και στα δύο προγράμματα περιήγησης αν υπάρχουν iframes παρούσα, και επιπλέον στον Firefox αν εκτελείται μέσα σε ένα από τα iframes.
Είναι ένα αρχαίο κομμάτι του κώδικα που έχω χρησιμοποιήσει μερικές φορές:
if (parent.location.href == self.location.href) {
window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
Είμαι χρησιμοποιώντας αυτό:
var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
if (window.frames.length != parent.frames.length) { page loaded in iframe }
Αλλά μόνο αν ο αριθμός των iframes διαφέρει σε σελίδα και τη σελίδα σας που σας φόρτωση σε iframe. Μην κάνετε κανένα iframe στη σελίδα σας για να έχετε 100% εγγύηση του αποτελέσματος αυτού του κώδικα
Γράψτε αυτό το javascript σε κάθε σελίδα
if (self == top)
{ window.location = "Home.aspx"; }
Στη συνέχεια, θα ανακατευθύνει αυτόματα στην αρχική σελίδα.
Αν θέλετε να μάθετε αν ο χρήστης έχει πρόσβαση η εφαρμογή σας από τη σελίδα facebook καρτέλα ή επιταγή καμβά για την υπογεγραμμένης αίτησης. Αν δεν το πάρει, κατά πάσα πιθανότητα ο χρήστης δεν έχει πρόσβαση από το facebook. Για να βεβαιωθείτε ότι επιβεβαιώνουν την signed_request δομή πεδία και τα πεδία περιεχομένου.
Με το php-SDK, μπορείτε να πάρετε το υπογεγραμμένης αίτησης ως εξής:
$signed_request = $facebook->getSignedRequest();
Μπορείτε να διαβάσετε περισσότερα για υπογεγραμμένης αίτησης εδώ:
https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/
και εδώ:
https://developers.facebook.com/docs/reference/login/signed-request/
window.frameElementΕπιστρέφει το στοιχείο (όπως <iframe> ή <αντικείμενο>) στην οποία το παράθυρο είναι ενσωματωμένο, ή null αν το παράθυρο είναι ανώτατου επιπέδου. Έτσι κωδικός ταυτοποίησης μοιάζει
if (window.frameElement) {
// in frame
}
else {
// not in frame
}
Αυτό είναι πρότυπο και όχι νέα μέθοδο. Λειτουργεί ακριβώς στο Chrome και Firefox. Δεν μπορώ να το προτείνω ως καθολική λύση, αλλά θα πρέπει να αναφερθεί εδώ νομίζω.
Εγώ πραγματικά χρησιμοποιούνται για τον έλεγχο window.parent και λειτούργησε για μένα, αλλά τον τελευταίο καιρό παράθυρο είναι ένα κυκλικό αντικείμενο και πάντα έχει ένα γονέα κλειδί, iframe ή καθόλου iframe.
Δεδομένου ότι οι παρατηρήσεις που προτείνουν σκληρά σύγκριση με window.parent έργα. Δεν είμαι σίγουρος αν αυτό θα λειτουργήσει αν iframe είναι ακριβώς η ίδια ιστοσελίδα ως μητρική.
window === window.parent;
Δεν είμαι σίγουρος πώς λειτουργεί αυτό το παράδειγμα για παλαιότερα προγράμματα περιήγησης στο Web, αλλά μπορώ να χρησιμοποιήσω αυτό για IE, Firefox και Chrome χωρίς και θέμα:
var iFrameDetection = (window === window.parent) ? false : true;
Best-για-τώρα Legacy Browser Πλαίσιο Breaking Script
Οι άλλες λύσεις δεν λειτούργησε για μένα. Αυτός λειτουργεί σε όλους τους browsers:
Ένας τρόπος για να υπερασπίσει ενάντια Clickjacking πρέπει να περιλαμβάνει ένα «καρέ-διακόπτη» σενάριο σε κάθε σελίδα, που δεν θα πρέπει να διαμορφωθεί. Η ακόλουθη μεθοδολογία θα αποτρέψει μια ιστοσελίδα από το να πλαισιώνεται ακόμη και σε παλαιότερα προγράμματα περιήγησης, που δεν υποστηρίζουν το X-Frame-Options-Header.
Στο στοιχείο του εγγράφου HEAD, προσθέστε την ακόλουθη:
<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>
Με αυτό τον τρόπο, ό, τι μπορεί να είναι στο κεφάλι έγγραφο και το μόνο που χρειάζεται μία μέθοδο / taglib στο API σας.
Παραπομπή: https://www.codemagi.com/blog/post/194
Αυτό κατέληξε να είναι η απλούστερη λύση για μένα.
<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>













