Piszę aplikację facebook opartą na iframe. Teraz chcę użyć tej samej strony HTML do renderowania normalnej strony internetowej, a także strony kanwy na Facebooku. Chcę wiedzieć, czy mogę ustalić, czy strona została załadowana w ramce iframe, czy bezpośrednio w przeglądarce?
javascript
facebook
iframe
akshat
źródło
źródło
Odpowiedzi:
Przeglądarki mogą blokować dostęp z
window.top
powodu tej samej zasady pochodzenia . Występują również błędy IE. Oto działający kod:top
iself
oba sąwindow
obiektami (wraz zparent
), więc widzisz, czy twoje okno jest oknem górnym.źródło
window.self !== window.top
powracatrue
po uruchomieniu od wewnątrz treściframe
, lubiframe
.W ramce iframe tego samego źródła co element nadrzędny
window.frameElement
metoda zwraca element (np.iframe
Lubobject
), w którym osadzone jest okno. W przeciwnym razie, jeśli przeglądasz w kontekście najwyższego poziomu lub jeśli ramka nadrzędna i podrzędna mają różne źródła, będzie to oceniaćnull
.Jest to standard HTML z podstawową obsługą we wszystkich nowoczesnych przeglądarkach.
źródło
frameElement
spowoduje zgłoszenie wyjątku SecurityError w elementach iframe pochodzących z różnych źródeł, zgodnie z W3C ( WHATWG twierdzi, że zamiast tego powinien zwrócić null). Możesz więc zawinąć go wtry...catch
instrukcję.null
do i pozaiframe
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.
RoBorg ma rację, ale chciałem dodać notatkę dodatkową.
W IE7 / IE8, kiedy Microsoft dodał Tabs do swojej przeglądarki, złamali jedną rzecz, która spowoduje spustoszenie w JS, jeśli nie będziesz ostrożny.
Wyobraź sobie ten układ strony:
Teraz w ramce „baz” klikasz link (bez celu, ładuje się w ramce „baz”), działa dobrze.
Jeśli strona, która zostanie załadowana, nazwijmy ją special.html, używa JS, aby sprawdzić, czy „it” ma ramkę nadrzędną o nazwie „bar”, zwróci wartość true (oczekiwana).
Powiedzmy teraz, że strona special.html podczas ładowania sprawdza ramkę nadrzędną (pod kątem istnienia i jej nazwy, a jeśli jest to „pasek”, ładuje się ponownie w ramce paska, np.
Na razie w porządku. Teraz nadchodzi błąd.
Powiedzmy, że zamiast klikać oryginalny link jak zwykle i ładować stronę special.html w ramce „baz”, kliknąłeś ją środkowo lub zdecydowałeś się otworzyć w nowej karcie.
Gdy ta nowa karta zostanie załadowana ( bez żadnych ramek nadrzędnych! ) IE przejdzie do niekończącej się pętli ładowania strony! ponieważ IE „kopiuje” strukturę ramki w JavaScript, tak że nowa karta MUSI mieć element nadrzędny, a ten element nadrzędny MA NAZWĘ „pasek”.
Dobrą wiadomością jest to, że sprawdzanie:
w tej nowej karcie zwraca wartość true, a zatem można przetestować ten dziwny warunek.
źródło
window.parent
.Akceptowana odpowiedź nie działała dla mnie w skrypcie zawartości rozszerzenia Firefox 6.0 (Addon-SDK 1.0): Firefox wykonuje skrypt zawartości w każdym: oknie najwyższego poziomu i we wszystkich elementach iframe.
Wewnątrz skryptu zawartości otrzymuję następujące wyniki:
Dziwną rzeczą w tym wyniku jest to, że zawsze jest taki sam, niezależnie od tego, czy kod jest uruchamiany w ramce iframe, czy w oknie najwyższego poziomu.
Z drugiej strony Google Chrome wydaje się, że mój skrypt zawartości wykonuje się tylko raz w oknie najwyższego poziomu, więc powyższe w ogóle nie działałoby.
To, co w końcu zadziałało dla mnie w skrypcie zawartości w obu przeglądarkach, to:
Bez iframe drukuje się
0:0
w oknie najwyższego poziomu zawierającym jedną klatkę1:1
, a także w jedynym iframe dokumentu, który drukuje0:1
.Dzięki temu moje rozszerzenie może określić w obu przeglądarkach, czy są obecne iframe, a dodatkowo w Firefoksie, czy jest uruchomione w jednym z iframe.
źródło
document.defaultView.self === document.defaultView.top
lubwindow !== window.top
. W skrypcie zawartości dodatku SDK dla Firefoksaself
obiekt globalny jest obiektem służącym do komunikacji ze skryptem głównym.Nie jestem pewien, jak działa ten przykład w starszych przeglądarkach internetowych, ale używam tego w IE, Firefox i Chrome bez problemu:
źródło
!(window===window.parent)
Używam tego:
źródło
.indexOf("HTMLIFrameElement")
:?Użyj tej funkcji javascript jako przykładu, jak to osiągnąć.
źródło
Najlepszy na razie skrypt do łamania starszych ramek przeglądarki
Inne rozwiązania nie działały dla mnie. Ten działa we wszystkich przeglądarkach:
Jednym ze sposobów obrony przed kliknięciem jest umieszczenie skryptu „przerywającego ramki” na każdej stronie, którego nie należy oprawiać w ramkę. Poniższa metodologia zapobiegnie kadrowaniu strony internetowej nawet w starszych przeglądarkach, które nie obsługują nagłówka X-Frame-Options-Header.
W elemencie HEAD dokumentu dodaj:
Najpierw zastosuj identyfikator do samego elementu stylu:
W ten sposób wszystko może znajdować się w dokumencie HEAD i potrzebujesz tylko jednej metody / taglib w swoim API.
Odniesienie: https://www.codemagi.com/blog/post/194
źródło
źródło
Ponieważ pytasz w kontekście aplikacji na Facebooku, możesz rozważyć wykrycie tego na serwerze, gdy zostanie wykonane pierwsze żądanie. Facebook przekaże wiele pytających danych, w tym klucz fb_sig_user, jeśli zostanie wywołany z elementu iframe.
Ponieważ prawdopodobnie musisz sprawdzić te dane i użyć ich w swojej aplikacji, użyj ich, aby określić odpowiedni kontekst do renderowania.
źródło
W rzeczywistości sprawdzałem window.parent i zadziałało to dla mnie, ale ostatnio okno jest obiektem cyklicznym i zawsze ma klucz nadrzędny, iframe lub brak iframe.
Ponieważ komentarze sugerują, że trudno porównywać z Window.Parent działa. Nie jestem pewien, czy to zadziała, jeśli element iframe jest dokładnie taki sam jak strona nadrzędna.
źródło
window.parent === window
jest prawdziwy. Twoja odpowiedź jest nieprawidłowa. I to porównanie może być użyte do sprawdzenia (przynajmniej w chrome, nie testowałem go w innych przeglądarkach).To starożytny fragment kodu, którego użyłem kilka razy:
źródło
(parent.location == self.location)
parent.location
. W przeciwnym razie zgłoszony zostanie wyjątekJeśli chcesz wiedzieć, czy użytkownik uzyskuje dostęp do Twojej aplikacji z karty strony na Facebooku lub kanwy, zaznacz Podpisane żądanie. Jeśli go nie dostaniesz, prawdopodobnie użytkownik nie ma dostępu z Facebooka. Aby upewnić się, że potwierdzono strukturę pól z podpisanymi żądaniami i zawartość pól.
Z php-sdk możesz uzyskać takie podpisane żądanie w następujący sposób:
Możesz przeczytać więcej o Podpisanym Żądaniu tutaj:
https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/
i tu:
https://developers.facebook.com/docs/reference/login/signed-request/
źródło
To zakończyło się dla mnie najprostszym rozwiązaniem.
źródło
Ale tylko wtedy, gdy liczba elementów iframe różni się na stronie i stronie, która ładuje Cię w ramce iframe. Nie rób iframe na swojej stronie, aby mieć 100% gwarancję wyniku tego kodu
źródło
Napisz javascript na każdej stronie
Następnie automatycznie przekieruje na stronę główną.
źródło