Доступ к родительскому URL из iframe

Хорошо, у меня есть страница, и на ней есть iframe. Что мне нужно сделать, так это на странице iframe узнать, что такое URL-адрес главной страницы.

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

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

... или другие подобные комбинации, поскольку кажется, что есть несколько способов получить одну и ту же информацию.

В любом случае, вот в чем проблема. Мой iframe находится в том же домене, что и главная страница, но не в том же SUB-домене. Так, например, у меня есть

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

а затем мой URL-адрес iframe

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

Когда я пытаюсь получить URL-адрес с pageB.html (страница iframe), я продолжаю получать ту же ошибку отказа в доступе. Получается, что даже поддомены считаются межсайтовым скриптингом, это правильно, или я что-то делаю не так?


person chronofwar    schedule 05.08.2010    source источник
comment
Можете ли вы просто передать его в URL-адресе фрейма? Такие как <iframe src="url?parent=parent-url"></iframe>   -  person Biagio Arobba    schedule 30.08.2016


Ответы (17)


Вы правы. Поддомены по-прежнему считаются отдельными доменами при использовании iframe. Можно передавать сообщения, используя postMessage(...), но другой JS API намеренно недоступны.

Также возможно получить URL-адрес в зависимости от контекста. См. Другие ответы для более подробной информации.

person Dan Herbert    schedule 05.08.2010
comment
вы МОЖЕТЕ взаимодействовать между двумя двумя. Но вы должны добавить следующий скрипт и в родительский, и в iframe: ‹script› document.domain = mydomain.com; ‹/script› - person George; 03.04.2015

Да, доступ к URL-адресу родительской страницы не разрешен, если iframe и главная страница не находятся в одном (под) домене. Однако, если вам просто нужен URL-адрес главной страницы (то есть URL-адрес браузера), вы можете попробовать следующее:

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

Примечание.

window.parent.location разрешено; он позволяет избежать ошибки безопасности в OP, которая вызвана доступом к свойству href: window.parent.location.href вызывает «Заблокирован кадр с источником ...»

document.referrer ссылается на "URI страницы, на которую указывает ссылка на эту страницу ". Это может не вернуть содержащий документ, если iframe местоположение определяется каким-либо другим источником, например:

  • Контейнер iframe @ домен 1
  • Отправляет дочерний iframe в домен 2
  • Но в дочернем iframe ... Домен 2 перенаправляет в Домен 3 (т. Е. Для аутентификации, возможно, SAML), а затем Домен 3 направляет обратно в Домен 2 (т. Е. Через отправку формы (), стандартный SAML техника)
  • Для дочернего iframe document.referrer будет Доменом 3, а не содержащим Доменом 1.

document.location относится к "объекту местоположения, который содержит информацию об URL-адресе документа »; предположительно текущий документ, то есть текущий открытый iframe. Когда window.location === window.parent.location, href iframe является тем же, что и href родительского элемента.

person Vaibhav    schedule 12.10.2011
comment
@Ash это будет, если окно и расположение родительского окна отличаются, вы находитесь внутри iframe. В этом случае используется реферер iframe. В противном случае это главное окно, поэтому он принимает document.location (реферер здесь недействителен, так как это будет предыдущая страница, а не родительская). - person Lumbendil; 18.10.2013
comment
@jepser, потому что ваш iframe находится внутри этого iframe. у вас никогда не будет доступа к верхней рамке, если она находится посередине. вложенные междоменные фреймы iframe ошибочны на многих уровнях. но вы можете обойти это, если установите document.domain на верхнем и самом внутреннем кадрах. может быть. - person gcb; 26.10.2013
comment
Этот ответ в сочетании с stackoverflow.com/a/5697801/216084 выполняет свою работу. - person ; 09.12.2013
comment
Или, чуть более компактно: var url = (parent !== window) ? document.referrer : document.location; - person thekingoftruth; 18.12.2014
comment
Обратите внимание, что это не работает, если контейнер расположен на вашем локальном хосте (или, в более общем смысле, если эта страница не открывается веб-сервером) или вызывается с помощью file: //. - person Guillaume Renoult; 05.02.2015
comment
Следует отметить, что это можно решить с помощью Referer-Policy заголовок. - person Dan Atkinson; 15.03.2017
comment
Похоже, это не работает с браузером Edge - реферер будет пустой строкой .. stackoverflow.com/questions/24169219/ - person Davide Orazio Montersino; 23.05.2017
comment
@thekingoftruth еще более кратко: var url = (self===top) ? document.URL : document.referrer; (два изменения: (1) использование положительной проверки вместо отрицательной; (2) document.location - это объект, поэтому вам нужно использовать document.location.href или document.URL). - person thdoan; 19.10.2018
comment
Будет ли это работать, если контейнер работает на ngrok? - person Sparlarva; 29.12.2018
comment
Пробовал это после нескольких других решений, и это сработало! В моем случае скрипт был выполнен внутри фрейма, расположенного на главной странице, с разными URL-адресами, но с одним и тем же хостом. - person jcf; 04.07.2019
comment
Это решение не будет работать, если у родительской страницы есть `‹ meta name = referrer content = no-referrer / ›` - person Miguel Mota; 08.05.2020
comment
Это решение не работает. Chrome блокирует перенаправление. - person Kamlesh; 02.01.2021

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

Допустим, в вашем iFrame вам нужен этот iframe: src = "http://www.example.com/mypage.php"

Что ж, вместо HTML для указания iframe используйте javascript для создания HTML для вашего iframe, получите родительский URL-адрес через javascript «во время сборки» и отправьте его как параметр URL-адреса GET в строке запроса вашей цели src, например так:

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

Затем найдите функцию анализа URL-адреса javascript, которая анализирует строку URL-адреса, чтобы получить переменную URL-адреса, которую вы ищете, в данном случае это «url».

Я нашел здесь отличный парсер строки URL: http://www.netlobo.com/url_query_string_javascript.html

person Gregory Lewis    schedule 18.04.2011
comment
Этот ответ в сочетании с stackoverflow.com/a/7739035/216084 выполняет свою работу. - person ; 09.12.2013
comment
Это было прекрасное предложение. Для тех, кто пишет родительский код iframe HTML, это оплачивает счет. В нашем программном обеспечении для пикселей мы использовали нечто очень похожее. - person Ligemer; 25.11.2014
comment
Спасибо!! Это эффективный обходной путь, который по-прежнему соблюдает межсайтовые правила. - person theUtherSide; 12.09.2015
comment
Но вы переписываете все URL-адреса в html на сервере? Потому что в противном случае, когда пользователь щелкает ссылку в iFrame, он все равно не будет доступен. - person Roel; 11.04.2016
comment
@Roel, вы можете написать их все во время сервера (по сути, жестко закодировать этот ответ), или этот ответ вы можете сделать в javascript, например, после загрузки страницы он вводит желаемые iframe. - person rogerdpack; 28.10.2016
comment
document.write считается плохой практикой по разным причинам. Это может сработать, но вы должны использовать его с осторожностью. Вот интересный блог об этом: блог. dareboost.com/en/2016/09/. Наряду с: stackoverflow .com / questions / 802854 / и stackoverflow.com/ questions / 18789190 / why-not-document-write - person Carnix; 11.04.2018

Если ваш iframe из другого домена (кросс-домен), вам просто нужно будет использовать это:

var currentUrl = document.referrer;

и - вот и основной URL!

person ParPar    schedule 28.10.2012
comment
В моем случае это не сработало, поскольку я думаю, что сам iFrame был динамически сгенерирован или проделал какие-то другие уловки. Во всяком случае, я не получил ожидаемого ответа. - person Muskie; 18.06.2013
comment
это должно работать во всех браузерах. Если только в новых браузерах вы не отправляете параметры песочницы, но я сомневаюсь, что это так. Это работает независимо от перекрестного домена. - person gcb; 26.10.2013
comment
Если страница внутри iframe перезагружается через javascript (например, window.location.reload(true)), это больше не работает. Тогда реферер - это URL-адрес самого iframe. - person mori; 26.03.2019

Следующая строка будет работать: document.location.ancestorOrigins[0] возвращает доменное имя предка.

person Robert-Jan Kuyper    schedule 19.09.2018
comment
После изменений, внесенных в Chrome, теперь это правильный ответ для многих браузеров. - person Dan Atkinson; 23.04.2019
comment
Но не полный URL. Только домен - person TheMaster; 22.07.2019
comment
document.location.ancestorOrigins возвращает undefined для меня - person Miguel Mota; 08.05.2020
comment
Что касается поддержки браузера, в частности, по состоянию на июль 2020 года ancestorOrigins еще не поддерживается в Firefox из-за проблем с конфиденциальностью. Запрос и обсуждение функции Bugzilla: bugzilla.mozilla.org/show_bug.cgi?id=1085214 < / а>. Поддержка браузера: caniuse.com/#search=ancestorOrigins - person colin moock; 04.07.2020

Для страниц в одном домене и другом субдомене вы можете установить свойство document.domain с помощью javascript.

И родительский фрейм, и iframe должны установить свой document.domain на что-то общее между ними.

т.е. www.foo.mydomain.com и api.foo.mydomain.com могут использовать либо foo.mydomain.com, либо просто mydomain.com и быть совместимыми (нет, вы не можете установить для них обоих com, по соображениям безопасности ...)

также обратите внимание, что document.domain - это улица с односторонним движением. Рассмотрите возможность выполнения следующих трех операторов по порядку:

// 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

Современные браузеры также могут использовать window.postMessage для передачи информации о происхождении, но это не будет работать в IE6. https://developer.mozilla.org/en/DOM/window.postMessage

person user409021    schedule 12.08.2010
comment
Пожалуйста, примите это как ответ, теперь, когда это возможно и этот ответ появляется в поиске Google. - person Metagrapher; 09.12.2013

Попробуй:

document.referrer

Когда вы меняете, вы находитесь в iframe, ваш хост - «реферер».

person Benjamim William L. Nunes    schedule 19.06.2019
comment
Сегодня в Chrome это не возвращает полный URL. Когда example.com?abc=123 загружает iframe, а вы запускаете document.referrer в iframe, он дает только example.com и удаляет часть ?abc=123. - person KingJulian; 21.12.2020

У меня были проблемы с этим. Если вы используете такой язык, как php, когда ваша страница впервые загружается в iframe, возьмите $_SERVER['HTTP_REFFERER'] и установите для него переменную сеанса.

Таким образом, когда страница загружается в iframe, вы знаете полный родительский URL-адрес и строку запроса страницы, которая ее загрузила. С кросс-браузерной безопасностью это немного головная боль, рассчитывая на window.parent что-нибудь, если вы используете разные домены.

person Hyzer Deeds    schedule 19.01.2012

Я обнаружил, что в случаях, когда $_SERVER['HTTP_REFERER'] не работает (я смотрю на вас, Safari), $_SERVER['REDIRECT_SCRIPT_URI'] был полезным резервным копированием.

person Dan    schedule 23.10.2012

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

Я обнаружил, что приведенный выше пример, предложенный ранее, работал, когда скрипт выполнялся в iframe, однако он не получал URL-адрес, когда скрипт выполнялся вне iframe, потребовалась небольшая корректировка:

var url = (window.location != window.parent.location) ? document.referrer: document.location.href;
person user3523340    schedule 11.04.2014
comment
Если вы находитесь за пределами iframe, значит, вы запускаете скрипт в родительском фрейме, вам не нужно ничего проверять. - person Art3mix; 08.12.2018

Мне не удалось заставить работать предыдущее решение, но я обнаружил, что если я установлю iframe scr, например, с http:otherdomain.com/page.htm?from=thisdomain.com/thisfolder, тогда я смогу в извлечении iframe thisdomain.com/thisfolder, используя следующий javascript:

var myString = document.location.toString();
var mySplitResult = myString.split("=");
fromString = mySplitResult[1];
person Paul    schedule 19.08.2011

Проблема с PHP $ _SERVER ['HTTP_REFFERER'] заключается в том, что он дает полный URL-адрес страницы, которая привела вас на родительскую страницу. Это не то же самое, что и сама родительская страница. Хуже того, иногда http_referer отсутствует, потому что человек ввел URL-адрес родительской страницы. Итак, если я перейду на вашу родительскую страницу с yahoo.com, тогда yahoo.com станет http_referer, а не ваша страница.

person TARKUS    schedule 23.04.2012

В Chrome можно использовать location.ancestorOrigins. Он вернет все родительские URL-адреса.

person Gena Moroz    schedule 05.09.2018

есть кроссбраузерный скрипт для получения родительского происхождения:

private getParentOrigin() {
  const locationAreDisctint = (window.location !== window.parent.location);
  const parentOrigin = ((locationAreDisctint ? document.referrer : document.location) || "").toString();

  if (parentOrigin) {
    return new URL(parentOrigin).origin;
  }

  const currentLocation = document.location;

  if (currentLocation.ancestorOrigins && currentLocation.ancestorOrigins.length) {
    return currentLocation.ancestorOrigins[0];
  }

  return "";
}

Этот код должен работать в Chrome и Firefox.

person Jose Antonio Fuentes    schedule 05.02.2021

Это сработало для меня, чтобы получить доступ к URL-адресу iframe src.

window.document.URL
person user1503606    schedule 25.10.2017

Я знаю, что он очень старый, но мне кажется, что никто не рекомендовал просто передавать файлы cookie из одного домена в другой. Поскольку вы используете поддомены, вы можете делиться файлами cookie из базового домена со всеми поддоменами, просто установив файлы cookie на URL .basedomain.com

Затем вы можете делиться любыми данными, которые вам нужны, через файлы cookie.

person Bruce    schedule 15.05.2019

Получить все родительские функции iframe и 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;
person vijay kumar    schedule 26.02.2018
comment
Я не думаю, что вы можете расширить этот ответ для тех из нас, кто не использует jQuery (я должен отметить, что их число растет, поскольку за последние несколько лет необходимость в jQuery стала увеличиваться). По крайней мере, я предлагаю пояснить, что этот ответ зависит от jQuery, а OP вообще не упоминал jQuery. - person Carnix; 11.04.2018