2012-10-24 11 views
24

Zrobiłem stronę, która zostanie załadowana do ramki IFrame i musi wywołać funkcję na stronie nadrzędnej po jej załadowaniu.Pozwolenie dziecku Iframe na wywołanie funkcji w oknie nadrzędnym z innej domeny

Działa lokalnie w rozwoju (w tej samej domenie), ale w świecie rzeczywistym jest ona utrzymywana na zupełnie innej domenie, więc oczywiście używam do Krzyża problemów domen, tj:

Niebezpieczne JavaScript próba dostępu ramka z adresem URL http: // [...] site1.com z ramki z adresem URL http: // [...] site2.com/iframe. Domeny, protokoły i porty muszą się zgadzać.

Kontroluję oba serwery, więc czy mogę umieścić coś na jednym lub obu serwerach, które mówią, że mogą ze sobą rozmawiać?

Przyjrzałem się ustawieniu "document.domain" zarówno na stronie elementu iframe, jak i stronie nadrzędnej.

Mam eksperymentował z ustawieniem żniwna dostępu Sterowanie:

nagłówek ('Access-Control-Allow-Origin: *');

Ale żadna z nich nie działa.

Czy jest jakiś sposób na umożliwienie iframe wywoływania funkcji w oknie nadrzędnym w zupełnie innej domenie, gdy kontroluję oba serwery?

+0

Ten [wpis] (http://stackoverflow.com/questions/5477324/iframe-calling-parent-javascript) zapewnia niezwykle proste rozwiązanie. – craned

Odpowiedz

70

Możesz komunikować się między klatkami poprzez message posting API.

Na przykład w ramce dziecka, może zadzwonić:

parent.postMessage("child frame", "*"); 

A w ramce nadrzędnej, zarejestrować obsługi wiadomość:

window.addEventListener("message", function(event) { 
    console.log("Hello from " + event.data); 
}); 
1

W nowoczesnych przeglądarkach można używać do komunikacji między współpracującymi ramkami w różnych domenach. Nie możesz bezpośrednio wywołać funkcji, ale możesz przekazywać dane lub wiadomości między nimi. Zobacz description on MDN.

2

Ten problem można łatwo rozwiązać, stosując przepisanie .htaccess.

Demo:

A. Utwórz katalog o nazwie "iframeContent /" na SERWERZE 1.

B. miejsce w tym katalogu plik o nazwie index.php zawierających:

<html> 
<head></head> 
<body> 

<script type="text/javascript"> 

    parent.check(); 

</script> 

</body> 
</html> 

To jest zawartość ramki iFrame. Będzie wywoływał funkcję w rodzicu.

C. Utwórz katalog o nazwie „iframeTesting_without-.htaccess /” na SERWERZE 2.

D. miejsce w tym katalogu plik o nazwie indeksu.php zawierający:

<html> 
<head></head> 
<body> 

<script type="text/javascript"> 

    function check() { 

     alert("hello"); 

    } 

</script> 

<iframe id="sidebnrId" name="sidebnr" 
src="PATH-ON-SERVER-1/iframeContent/" frameborder="0" 
height="500px" width="600px" scrolling="no"></iframe> 

</script> 

</body> 
</html> 

Jest to po prostu zawartość okien macierzystych. Pamiętaj, że zawartość iFrame znajduje się na innym serwerze (ponieważ na SERVER 1).

E. Dostęp do "PATH-ON-SERVER-2/iframeTesting_without-htaccess /" przy użyciu przeglądarki internetowej -> nic się nie dzieje: element iframe nie ma dostępu do funkcji rodzica.

Oto jak TY może rozwiązać problem

F. utworzyć kolejny katalog o nazwie "iframeTesting_with-.htaccess /" na SERWERZE 2.

G. miejsce w tym katalogu plik o nazwie index.php zawierające:

<html> 
<head></head> 
<body> 

<script type="text/javascript"> 

    function check() { 

     alert("hello"); 

    } 

</script> 

<iframe id="sidebnrId" name="sidebnr" 
src="content-iframe/" frameborder="0" 
height="500px" width="600px" scrolling="no"></iframe> 

</script> 

</body> 
</html> 

tym razem iFrame nie wskazuje już bezpośrednio do kon namiot na SERWER 1, ale na pośredni fikcyjny katalog "content-iframe /" znajdujący się na tym samym serwerze (SERVER 2).

H. miejsce w tym katalogu plik .htaccess zawierający:

Options +FollowSymLinks 
RewriteEngine On 

RewriteBase/

RewriteRule ^content-iframe/$ PATH-ON-SERVER-1/iframeContent/ [R,NC,P] 

Rola tego pliku jest przekierowanie żadnego dostępu do katalogu fikcyjnej do zawartości na serwerze 1.

I. Spróbuj ponownie, uzyskaj dostęp do "PATH-ON-SERVER-2/iframeTesting_with-htaccess /" za pomocą przeglądarki internetowej. Tym razem to zadziała. Mam nadzieję, że pomogło :-)