2009-08-16 3 views
1

Итак, у меня есть два документа dA и dB, размещенные на двух разных серверах sA и sB соответственно.Как получить javascript в iframe для изменения родительского документа?

В документе dA есть несколько JS, которые открывают документ iframe src'ing dB с формой на нем. когда форма в документе dB передается обработчику формы на сервере sB, я хочу, чтобы iframe на странице dA закрывался.

Я надеюсь, что было достаточно ясно. Есть ли способ сделать это?

Спасибо!

-Mala

UPDATE: У меня нет никакого контроля над дА или SÁ кроме через вставленную JavaScript

+0

Как явствует из ответов ниже, что, если я хочу изменить дА, то JS должен прийти из дА - так подобный вопрос: могу ли я иметь кнопку на dA представить форму в дБ? – Mala

+0

Нет, все еще невозможно без доступа к dA/sA. – Mark

ответ

0

Спасибо всем за ваши ответы. Я нашел решение, которое работает:

На моем сервере я передаю форму для перенаправления на URL-адрес, который создал iframe. На сайте, содержащем iframe, я добавляю функцию setInterval для опроса текущего местоположения iframe.

Из-за песочницы JS этот опрос не работает, в то время как URL-адрес является иностранным (то есть перед отправкой моей формы). Однако, как только URL-адрес является локальным (то есть идентичным URL-адресу вызывающей страницы), URL-адрес доступен для чтения, а функция закрывает iframe. Это работает, как только iframe перенаправляется, мне даже не нужно ждать дополнительной pageload.

Большое спасибо Грегу за помощь мне :)

3

Это не должно быть возможным благодаря политике браузера песочнице безопасности/JavaScript. При этом можно выйти за пределы этих ограничений с небольшим количеством хакеров. Существует множество методов, некоторые из которых связаны с Flash.

я бы не рекомендовал делать это, если это возможно, но если надо, я бы порекомендовал DNS подход называют здесь:

http://www.alexpooley.com/2007/08/07/how-to-cross-domain-javascript/

Key Выдержки:

Say domain D wants to connect to domain E. In a nutshell, the trick is to use DNS to point a sub-domain of D, D_s, to E’s server. In doing so, D_s takes on the characteristics of E, while also being accessible to D.

0

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

Безопасный подход ограничил бы только документ iframe, опустошающий/скрывающийся сам, но если iframe содержит его фиксированный размер, вы просто получите пустое место на странице.

+0

Как я могу сам сделать размер iframe вертикально зависимым от содержимого фрейма? Это решит мою проблему в том, что я мог бы просто показать iframe пустую страницу, чтобы «удалить» ее – Mala

0

Если у вас нет контроля над dA или Sa, это невозможно из-за ограничений безопасности браузера. Даже Flash-методы требуют доступа к обоим серверам.

2

Предположим, что я создаю страницу A, которая лежит с рамкой, которая охватывает всю страницу. Позвоните по ссылке на yourbank.com, и вы нажмете на эту ссылку. Теперь, если бы я мог использовать javascript, который изменяет содержимое фрейма (банковский сайт), я мог бы легко прочитать пароль, который вы используете, и сохранить его в файле cookie, отправить его на мой сервер и т. Д.

Именно по этой причине вы не можете изменять контент в другом фрейме, содержимое которого НЕ принадлежит одному домену. Однако, если они принадлежат одному домену, вы должны иметь возможность изменять его по своему усмотрению (обе страницы должны быть на вашем сервере).

Вы должны быть в состоянии получить доступ к IFRAME с этим кодом:

window["iframe_name"].document.body 
2

Другие люди объяснили последствия для безопасности. Но вопрос законный, для этого есть примеры использования, и в некоторых сценариях можно делать то, что вы хотите.

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

Руководящий документ: DOM Level 1 Spec. Посмотрите на the description of document.Как вы видите, это свойство определено там и & hellip; он доступен только для чтения. В действительности все браузеры позволяют изменить его:

Модификации не могут быть произвольными. Обычно допускаются только супердомены. Это означает, что вы можете сделать два документа, обслуживаемых другим сервером, для доступа друг к другу, если у них есть общий супер-домен.

Так что если вы хотите, чтобы две страницы связывались, вам нужно добавить небольшой однострочный вкладыш, который должен запускаться при загрузке страницы. Нечто подобное должно сделать трюк:

document.domain = "yourdomain.com"; 

Теперь вы можете обслуживать их с разных поддоменов, не теряя при их доступности.

Очевидно, что вам следует следить за сроками. Их можно избежать, если вы установили какой-либо протокол уведомления. Например, одна страница (мастер) устанавливает свой домен и загружает другую страницу (сервер). Когда сервер работает, он изменяет свой домен и обращается к мастеру, запускающему некоторую функцию.

+0

Просто невероятно. Я никогда не слышал об этой технике. С Chrome и Safari вы даже можете передать простой домен верхнего уровня в сеттер ... – user123444555621

+0

Я знаю, что это старый, но для справки в будущем кажется, что хром заблокировал это. Теперь он возвращает: «Непринятая ошибка: SECURITY_ERR: исключение DOM 18». –

3

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

window.top.location = "http://www.example.com/dC.html"; 

Это закроет дА и отправил пользователю dC.html вместо. dC.html может иметь JS, который вы хотите запустить (например, закрыть окно) в обработчике onload.

0

Это немного запутанный, но может быть более законными, чем прямой раствор XSS:

Вы не имеете никакого контроля над сервером А кроме написания JavaScript для документа А. Но вы открывающий IFRAME внутри документа A, который предполагает, что у вас есть только доступ на запись к документу A. Это немного сбивает с толку. Вы пишете js для документирования A или впрыскивания его каким-то образом?

В любом случае, вот что я придумал. Это не сработает, если у вас нет доступа к серверу, на котором размещена страница с iframe.

Пользователь обращается к форме в пределах iframe. Форма, после завершения которой, скорее всего, что-то изменяет на сервере, на котором размещена эта форма. Таким образом, у вас есть функция AJAX в документе A, которая запрашивает серверный скрипт, чтобы проверить, была ли еще представлена ​​форма. Если это так, скрипт возвращает «отправленное» значение функции AJAX, которая запускает другую функцию js для закрытия iframe.

выше требует несколько вещей:

  • Функция Iframe должна быть на страницу, размещенную на сервере, где вы можете написать дополнительный серверный скрипт (это позволяет избежать проблемы кросс-временной области, так AJAX указывает на тот же каталог, теоретически).

  • Сервер в пределах iframe должен иметь URL-адрес, который может быть запрошен, который вернет какое-то подтверждение о том, что форма была отправлена.

  • Скрипт «check-for-submit» должен знать как вышеупомянутый URL-адрес, так и что искать при загрузке указанного URL-адреса.

Если у вас есть все вышеизложенные, Аякс функция вызывает серверный скрипт, сервер-скрипт использует Curl идти URL, который отражает, если форма будет сделана, сервер-скрипт выглядит для " форма была представлена ​​«индикаторами», и, в зависимости от того, что она находит, возвращает ответ «не представлен» или «отправлен» функции ajax.

Например, возможно, форма предназначена для регистрации пользователя. Если ваш внешний документ знает, какое имя пользователя будет введено в форму, скрипт на стороне сервера может перейти в http://example.org/username, и если он появится с «пользователем не найденным», вы знаете, что форма еще не отправлена.

Все, что выходит за рамки того, что возможно в приведенном выше примере, вероятно, находится вне того, что безопасно и безопасно в любом случае. Хотя было бы очень удобно автоматически закрывать iframe, когда пользователь отправил его, подумайте о том, что я отправил вам электронное письмо, в котором вам нужен ваш банковский счет. В электронном письме есть ссылка на страницу, которую я создал, на которой установлен сайт iframe вашего банка, чтобы заполнить всю просматриваемую часть моей страницы. Вы входите в систему как обычно, потому что вы очень доверяете. Если бы у меня был доступ к тому факту, что вы нажали кнопку «Отправить» на странице, это означало бы, что у меня также был доступ к тому, что вы отправили или, по крайней мере, к URL-адресу, к которому перенаправлен iframe (который может иметь идентификатор сеанса или всевозможные другие данные, которые банк не должен включать в URL-адрес).

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

Я думаю, что немного менее изящное решение вашей проблемы было бы иметь ссылку над iframe, которая говорит «Закончена» или «Закрыть», которая убивает iframe, когда пользователь закончил с формой. Это не только закроет iframe, когда пользователь представит форму, но и предоставит им возможность сказать «oops! Я не хочу заполнять эту форму в любом случае. Nevermind!» Прямо сейчас с вашим желаемым автоматическим решением, нет способа избавиться от iframe, если пользователь не попадет в submit.

Смежные вопросы