Изменение URL родительского окна из IFrame - PullRequest
14 голосов
/ 07 декабря 2009

У меня есть ситуация, когда у меня есть веб-приложения на двух разных серверах, где App1 содержит App2 в IFrame. Любые ссылки в App2 могут иметь атрибут target="_parent", который позволяет открывать эти ссылки в верхнем окне. Тем не менее, я не могу найти способ получить такое же поведение в Javascript. Я обнаружил эту страницу , которая утверждает , что дочерний фрейм может вызывать javascript для родительского фрейма, используя parent.foo(), но это не работает в IE8 или FF3.5. Я нашел этот вопрос , который объясняет, как работает эта модель безопасности. Но кажется странным, что я не могу сделать в Javascript то, что я могу сделать с простым тегом <a>. Есть ли какой-нибудь обходной путь? Я знаю о window.postMessage , но (насколько я знаю) это работает только в Firefox.


Пример

сервер1 / test.html

<html>
<head>
<script type="text/javascript">
function myCallback(foo) {
  alert(foo);
}
</script>
</head>
<body>
<iframe src="http://server2/test2.htm" width="400" height="150"></iframe>
</body></html>

server2 / test2.html

<html><body>
<script>
function clickit() {
  parent.document.location = "http://www.google.com"; //not allowed
  parent.myCallback("http://www.google.com"); //not allowed
}
</script>
<p>This should be in an iFrame!</p>
<p><a href="http://www.google.com" target="_parent">normal link (works)</a></p>
<p><a href="javascript:clickit()">javascript link</a></p>
</body></html>

Ответы [ 5 ]

13 голосов
/ 07 декабря 2009

ОК. Я провел дополнительное исследование, и оказалось, что postMessage работает во всех современных браузерах, даже в IE (с оговоркой, что IE имеет немного другой способ сделать это). Вот как я заставил его работать (проверено на WinXP в IE8, FF3.5, Chrome 3.0, Safari 4 beta, Opera 9.64):

сервер1 / test.html

<html>
<head>
<script type="text/javascript">
if(navigator.appName == "Microsoft Internet Explorer")
  window.attachEvent("onmessage", receiveMessage);
else
  window.addEventListener("message", receiveMessage, false);

function receiveMessage(e) {
  if(e.origin == "http://server2") //important for security
    if(e.data.indexOf('redirect:') == 0)
      document.location = e.data.substr(9);
}
</script>
</head>
<body>
<iframe src="http://server2/test2.htm" width="400" height="150"></iframe>
</body>
</html>

server2 / Test2.htm

<html><body>
<script>
function clickit() {
  parent.postMessage('redirect:http://www.google.com', 'http://server1');
}
</script>
<p>This should be in an iFrame!</p>
<p><a href="http://www.google.com" target="_parent">normal link</a></p>
<p><a href="javascript:clickit()">javascript link</a></p>
</body></html>
4 голосов
/ 07 января 2013

Простая вещь, которую вы можете сделать: выполнить следующее из кода JavaScript страницы iframe

top.location = "https://www.google.co.in/";

это изменит расположение URL окна на https://www.google.co.in/.

Еще одна вещь - эта стратегия также может быть полезна, когда вы не хотите, чтобы кто-либо мог вмешиваться в ваш сайт просто напишите приведенный выше код в готовой части документа.

2 голосов
/ 07 декабря 2009

Нет, и не зря. Если вам это нужно, то вы должны запустить все коммуникации через один из двух серверов; например, пусть server1 действует как прокси для всех запросов на «server2 / test2.html».

1 голос
/ 07 декабря 2009

Если родительский элемент и iframe находятся на поддоменах в одном домене, вы можете иметь возможность что-то сделать со свойством document.domain. Если и тело, и iframe рассматриваются как имеющие одно и то же происхождение, изменение местоположения должно быть возможным; Я не пробовал это сам. Некоторые читают здесь

0 голосов
/ 07 декабря 2009

Если кадры находятся в одном домене, вы должны иметь доступ к родительскому кадру. В противном случае это проблема безопасности.

Единственный обходной путь, который приходит на ум, - это использовать AJAX для обновления файла на каждом из серверов, а затем проверить содержимое противоположной стороны файлового сервера. Вы можете сделать то же самое, используя одну базу данных, если разрешите подключения из внешних доменов.

Хотя это все излишнее, когда вы можете просто открыть ссылку во фрейме и попросить пользователей нажать на нее, чтобы продолжить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...