Uzyskaj dostęp do nadrzędnego adresu URL z elementu iframe

187

Ok, mam stronę na tej stronie i iframe. Co muszę zrobić, to na stronie iframe dowiedzieć się, jaki jest adres URL strony głównej.

Szukałem i wiem, że nie jest to możliwe, jeśli moja strona iframe znajduje się w innej domenie, ponieważ jest to skrypt między witrynami. Ale wszędzie, gdzie czytałem, mówi, że jeśli strona iframe znajduje się w tej samej domenie co strona nadrzędna, powinna działać, jeśli na przykład:

parent.document.location
parent.window.document.location
parent.window.location
parent.document.location.href

... lub inne podobne kombinacje, ponieważ wydaje się, że istnieje wiele sposobów uzyskania tych samych informacji.

W każdym razie, więc jest problem. Mój iframe znajduje się w tej samej domenie co strona główna, ale nie w tej samej domenie SUB. Tak na przykład mam

http: // www.mysite.com/pageA.html

a następnie mój URL iframe to

http: // qa-www.mysite.com/pageB.html

Gdy próbuję pobrać adres URL z pageB.html(strony iframe), ciągle pojawia się ten sam błąd odmowy dostępu. Wygląda więc na to, że nawet subdomeny liczą się jako skrypty między witrynami, czy to prawda, czy robię coś złego?

chronofwar
źródło
Czy możesz to przekazać w adresie URL ramki? Takich jak<iframe src="url?parent=parent-url"></iframe>
Biagio Arobba

Odpowiedzi:

21

Masz rację. Subdomeny są nadal uważane za osobne domeny podczas korzystania z ramek iframe. Możliwe jest przekazywanie wiadomości przy użyciu postMessage(...), ale inne interfejsy API JS celowo stają się niedostępne.

Nadal można uzyskać adres URL w zależności od kontekstu. Zobacz inne odpowiedzi, aby uzyskać więcej informacji.

Dan Herbert
źródło
1
Okej, to po prostu wieje. Ale przynajmniej wiem, że nie wariuję :( no cóż, plan B. dzięki. (I przepraszam, że nie
umieściłem
9
jak to jest wybrana odpowiedź? są o wiele lepsze opisy możliwych rozwiązań poniżej.
Anoyz
1
Zgoda! Odpowiedź poniżej z 80 głosami jest znacznie lepsza. Ta odpowiedź znajduje się w specyfikacji HTML.
Ligemer
4
MOŻESZ wchodzić w interakcje między 2. Ale musisz dodać następujący skrypt zarówno dla elementu nadrzędnego, jak i elementu iframe: <script> document.domain = "mydomain.com"; </script>
George
2
„Aby uzyskać więcej informacji, zobacz inne odpowiedzi”. hahah To tak: nie mam żadnego rozwiązania, widzę inne odpowiedzi, ale akceptuję również moją odpowiedź.
Milad
371

Tak, dostęp do adresu URL strony nadrzędnej jest niedozwolony, jeśli ramka iframe i strona główna nie znajdują się w tej samej (pod) domenie. Jeśli jednak potrzebujesz tylko adresu URL strony głównej (tj. Adresu URL przeglądarki), możesz spróbować:

var url = (window.location != window.parent.location)
            ? document.referrer
            : document.location.href;

Uwaga:

window.parent.locationjest dozwolone; pozwala uniknąć błędu bezpieczeństwa w OP, który jest spowodowany dostępem do hrefwłaściwości: window.parent.location.hrefpowoduje „Zablokowano ramkę z początkiem ...”

document.referrerodnosi się do „identyfikatora URI strony, która prowadzi do tej strony”. To może nie zwrócić dokumentu zawierającego, jeśli inne źródło określiło iframelokalizację, na przykład:

  • Kontener iframe @ Domena 1
  • Wysyła iframe potomne do Domeny 2
  • Ale w elemencie iframe potomnym ... Domena 2 przekierowuje do Domeny 3 (tj. W celu uwierzytelnienia, być może SAML), a następnie Domena 3 przekierowuje z powrotem do Domeny 2 (tj. Poprzez przesłanie formularza (), standardową technikę SAML)
  • Dla elementu iframe podrzędnego document.referrerbędzie to Domena 3 , a nie Domena zawierająca 1

document.locationodnosi się do „obiektu lokalizacji, który zawiera informacje o adresie URL dokumentu”; prawdopodobnie obecny dokument, czyli iframe obecnie otwarty. Kiedy window.location === window.parent.location, wtedy iframe hrefjest taki sam jak zawierający rodzic href.

Vaibhav
źródło
1
@ jepser, ponieważ twoja rama iframe znajduje się w tej ramce. nigdy nie będziesz miał dostępu do górnej ramki z tą na środku. Zagnieżdżone iframe między domenami jest błędne na tak wielu poziomach. ale możesz to obejść, jeśli ustawisz document.domainna górnej i wewnętrznej ramie. może.
gcb
2
Lub, nieco bardziej var url = (parent !== window) ? document.referrer : document.location;
zwięźle
2
Pamiętaj, że to nie działa, jeśli kontener znajduje się na twoim lokalnym hoście (lub bardziej ogólnie, jeśli ta strona nie jest otwarta przez serwer WWW) lub wywoływany przez plik: //.
Guillaume Renoult,
5
Należy zauważyć, że można to pokonać za pomocą Referer-Policynagłówka.
Dan Atkinson,
2
To nie wydaje się pracy z przeglądarką Edge - wywołującej będzie pusty ciąg .. stackoverflow.com/questions/24169219/...
Davide Orazio Montersino
51

Właśnie odkryłem obejście tego problemu, które jest tak proste, a jednak nigdzie nie znalazłem żadnych dyskusji na ten temat. Wymaga kontroli nadrzędnej ramki.

W ramce iFrame powiedz, że chcesz tę ramkę iframe: src = "http://www.example.com/mypage.php"

Cóż, zamiast HTML do określenia iframe, użyj javascript do zbudowania HTML dla twojego iframe, pobierz URL-a nadrzędnego przez javascript „w czasie kompilacji” i wyślij go jako parametr GET url w zapytaniu twojego obiektu src, jak więc:

<script type="text/javascript">
  url = parent.document.URL;
  document.write('<iframe src="http://example.com/mydata/page.php?url=' + url + '"></iframe>');
</script>

Następnie znajdź sobie funkcję parsowania adresu URL javascript, która analizuje ciąg adresu URL, aby uzyskać zmienną adresu URL, której szukasz, w tym przypadku jest to „url”.

Znalazłem świetny parser ciągów adresów URL tutaj: http://www.netlobo.com/url_query_string_javascript.html

Gregory Lewis
źródło
Ta odpowiedź w połączeniu z stackoverflow.com/a/7739035/216084 wykonuje zadanie.
2
To była cudowna sugestia. Dla tych, którzy piszą nadrzędny kod iframe HTML, będzie to kosztować. W naszym oprogramowaniu pikselowym zastosowaliśmy coś bardzo podobnego.
Ligemer,
Dziękuję Ci!! Jest to skuteczne obejście, które nadal przestrzega zasad dotyczących różnych witryn.
theUtherSide
Ale czy przepisujesz wszystkie adresy URL w html na serwerze? Ponieważ w przeciwnym razie użytkownik kliknie link w ramce iFrame, nadal nie będzie dostępny.
Roel
@Roel, możesz napisać je wszystkie w czasie serwera (w istocie „hard code” tę odpowiedź) lub tę odpowiedź, którą możesz zrobić w javascript, na przykład po załadowaniu strony wstrzykuje pożądane elementy iframe.
rogerdpack
34

Jeśli element iframe pochodzi z innej domeny (między domenami), wystarczy użyć tego:

var currentUrl = document.referrer;

i - tutaj masz główny adres URL!

PARPAR
źródło
To nie zadziałało w moim przypadku, ponieważ myślę, że sama iFrame została wygenerowana dynamicznie lub zrobiła inne oszustwo. W każdym razie nie otrzymałem odpowiedzi, której się spodziewałem.
Muskie
powinno to działać we wszystkich przeglądarkach. Chyba że w nowszych przeglądarkach wyślesz parametry piaskownicy, ale wątpię, by tak było. Działa to niezależnie od domeny.
gcb
Jeśli strona wewnątrz iframe przeładuje się za pomocą javascript (np. window.location.reload(true)), To już nie działa. Następnie strona odsyłająca to adres URL samego elementu iframe.
mori
20

W przypadku stron w tej samej domenie i innej subdomenie możesz ustawić tę document.domainwłaściwość za pomocą javascript.

Zarówno ramka nadrzędna, jak i ramka iframe muszą ustawić swoją dokument.domain na coś, co jest między nimi wspólne.

tzn. www.foo.mydomain.comi api.foo.mydomain.comkażdy może używać albo foo.mydomain.comalbo tylko mydomain.comi być kompatybilny (nie, nie można ustawić ich obu ze comwzględów bezpieczeństwa ...)

zauważ również, że document.domain to ulica jednokierunkowa. Rozważ uruchomienie następujących trzech instrukcji w kolejności:

// assume we're starting at www.foo.mydomain.com
document.domain = "foo.mydomain.com" // works
document.domain = "mydomain.com" // works
document.domain = "foo.mydomain.com" // throws a security exception

Nowoczesne przeglądarki mogą także korzystać z window.postMessage do komunikowania się między źródłami, ale nie będzie działać w IE6. https://developer.mozilla.org/en/DOM/window.postMessage

użytkownik409021
źródło
3
Zaakceptuj to jako odpowiedź, ponieważ jest to zarówno możliwe, jak i ta odpowiedź pojawia się w wynikach wyszukiwania Google.
Metagrapher,
17

Działa następujący wiersz: document.location.ancestorOrigins[0]ten zwraca nazwę domeny przodka.

Robert-Jan Kuyper
źródło
Po zmianach wprowadzonych w Chrome jest to poprawna odpowiedź dla wielu przeglądarek.
Dan Atkinson,
Jednak nie pełny adres URL. Tylko domena
TheMaster
document.location.ancestorOriginswraca undefineddo mnie
Miguel Mota
Jeśli chodzi o obsługę przeglądarki, w szczególności od lipca 2020 r., PrzodekOrigins nie jest jeszcze obsługiwany w przeglądarce Firefox z powodu obaw o prywatność. Zapytanie o funkcję Bugzilli i dyskusja: bugzilla.mozilla.org/show_bug.cgi?id=1085214 . Obsługa przeglądarki: caniuse.com/#search=ancestorOrigins
colin moock
9

Spróbuj:

document.referrer

Po zmianie jesteś w ramce iframe, twój host jest „polecającym”.

Benjamim William L. Nunes
źródło
2

Miałem z tym problemy. Jeśli używasz języka takiego jak php, gdy strona ładuje się po raz pierwszy w ramce iframe, $_SERVER['HTTP_REFFERER']ustaw ją na zmienną sesyjną.

W ten sposób, gdy strona ładuje się do ramki iframe, znasz pełny nadrzędny adres URL i ciąg zapytania strony, która go załadowała. Dzięki bezpieczeństwu w różnych przeglądarkach jest trochę kłopotliwy, licząc na window.parent wszystko, jeśli masz różne domeny.

Czyny Hyzera
źródło
2
var url = (window.location != window.parent.location) ? document.referrer: document.location;

Odkryłem, że powyższy sugerowany przykład działał wcześniej, gdy skrypt był wykonywany w ramce iframe, jednak nie pobierał adresu URL, gdy skrypt był wykonywany poza ramką iframe, wymagana była niewielka korekta:

var url = (window.location != window.parent.location) ? document.referrer: document.location.href;
użytkownik3523340
źródło
2
Jeśli znajdujesz się poza ramką iframe, uruchamiasz skrypt w ramce nadrzędnej, nie musisz niczego sprawdzać.
Art3mix,
1

Nie mogłem sprawić, aby poprzednie rozwiązanie działało, ale dowiedziałem się, że jeśli ustawię np. Iframe scr http:otherdomain.com/page.htm?from=thisdomain.com/thisfolder, to w ekstrakcie iframe mógłbym to zrobić thisdomain.com/thisfolderza pomocą następującego javascript:

var myString = document.location.toString();
var mySplitResult = myString.split("=");
fromString = mySplitResult[1];
Paweł
źródło
1

Problem z PHP $ _SERVER ['HTTP_REFFERER'] polega na tym, że podaje on w pełni kwalifikowany URL strony, która doprowadziła cię do strony nadrzędnej. To nie to samo, co sama strona nadrzędna. Co gorsza, czasami nie ma http_referer, ponieważ osoba wpisała adres URL strony nadrzędnej. Jeśli więc przejdę na twoją stronę nadrzędną z yahoo.com, wtedy yahoo.com stanie się http_referer, a nie twoją stroną.

TARKUS
źródło
1

Znalazłem w przypadkach, w których $_SERVER['HTTP_REFERER']nie działa (patrzę na ciebie, Safari), $_SERVER['REDIRECT_SCRIPT_URI']był przydatną kopią zapasową.

Dan
źródło
0

W chrome można użyć location.ancestorOrigins Zwróci wszystkie adresy URL rodziców

Gena Moroz
źródło
0

Wiem, że jest on bardzo stary, ale budzi to w moich myślach nikt nie zalecał przekazywania plików cookie z jednej domeny do drugiej. Podczas korzystania z subdomen możesz udostępniać pliki cookie z domeny podstawowej do wszystkich subdomen po prostu ustawiając pliki cookie na adres URL.basedomain.com

Następnie możesz udostępniać potrzebne dane za pomocą plików cookie.

Bruce
źródło
-1

To działało dla mnie, aby uzyskać dostęp do adresu URL iframe src.

window.document.URL
użytkownik1503606
źródło
-4

Uzyskaj wszystkie funkcje nadrzędnego elementu iframe i HTML

var parent = $(window.frameElement).parent();
        //alert(parent+"TESTING");
        var parentElement=window.frameElement.parentElement.parentElement.parentElement.parentElement;
        var Ifram=parentElement.children;      
        var GetUframClass=Ifram[9].ownerDocument.activeElement.className;
        var Decision_URLLl=parentElement.ownerDocument.activeElement.contentDocument.URL;
Vijay Kumar
źródło
Nie sądzę, że możesz rozszerzyć tę odpowiedź na tych z nas, którzy nie używają jQuery (rosnąca liczba, należy zauważyć, ponieważ jQuery staje się coraz bardziej niepotrzebny w ciągu ostatnich kilku lat). Przynajmniej sugeruję wyjaśnienie, że odpowiedź zależy od jQuery, a OP w ogóle nie wspomniało o jQuery.
Carnix