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

187

Хорошо, у меня есть страница, и на этой странице у меня есть 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

а затем мой iframe URL

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

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

chronofwar
источник
Вы можете просто передать его во фрейме URL? Такие как<iframe src="url?parent=parent-url"></iframe>
Бьяджо Аробба

Ответы:

21

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

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

Дэн Герберт
источник
1
Хорошо, хорошо, что просто дует. Но, по крайней мере, я знаю, что я не схожу с ума :( ну, хорошо, планирую Б. спасибо. (И извините за то, что не помещаю мои вещи в теги, спасибо за редактирование)
chronofwar
9
как это будет выбранный ответ? Ниже приведены гораздо лучшие описания возможных решений.
Анойз,
1
Согласовано! Ответ ниже с 80 голосами намного лучше. Этот ответ находится в спецификации HTML.
Ligemer
4
вы МОЖЕТЕ взаимодействовать между 2. Но вы должны добавить следующий скрипт как для parent, так и для iframe: <script> document.domain = "mydomain.com"; </ script>
Джордж
2
«Смотрите другие ответы для более подробной информации.» хахах Это похоже на: у меня нет никакого решения, вижу другие ответы, но также принимаю мой ответ.
Милад
371

Да, доступ к 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ссылается на «объект Location, который содержит информацию об URL документа»; предположительно текущий документ, то есть iframe, открытый в данный момент. Когда window.location === window.parent.location, то IFrame - х hrefэто же как содержащий родитель это href.

Vaibhav
источник
1
@jepser, потому что ваш iframe находится внутри этого iframe. у вас никогда не будет доступа к верхнему фрейму с этим в середине. вложенные междоменные iframes неправильны на многих уровнях. но вы можете обойти это, если установите document.domainверхний и самый внутренний фрейм. может быть.
13
2
Или, немного более компактно:var url = (parent !== window) ? document.referrer : document.location;
thekingoftruth
2
Обратите внимание, что он не работает, если контейнер расположен на вашем локальном хосте (или, в более общем случае, если эта страница не открыта веб-сервером) или вызывается по файлу: //.
Гийом Рено
5
Следует отметить, что это можно победить с помощью Referer-Policyзаголовка.
Дэн Аткинсон
2
Это не похоже на работу с пограничного браузера - реферер будет пустой строкой .. stackoverflow.com/questions/24169219/...
Davide Орацио Montersino
52

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

В вашем iFrame, скажем, вы хотите этот iframe: src = "http://www.example.com/mypage.php"

Ну, вместо HTML, чтобы указать iframe, используйте javascript для построения HTML для вашего iframe, получите родительский URL через javascript «во время сборки» и отправьте его в качестве параметра GET url в строке запроса вашей цели 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

Грегори Льюис
источник
Этот ответ в сочетании со stackoverflow.com/a/7739035/216084 выполняет свою работу.
2
Это было замечательное предложение. Для тех, кто пишет родительский html-код iframe, это поможет. Мы использовали что-то очень похожее в нашей пиксельной программе.
Ligemer
Спасибо!! Это эффективный обходной путь, который все еще соблюдает межсайтовые правила.
TheStherSide
Но вы переписываете все URL-адреса в HTML на сервере? Потому что в противном случае, когда пользователь щелкает ссылку в iFrame, она все равно будет недоступна.
Roel
@Roel вы могли бы написать их все во время сервера (по сути, «жесткий код» этого ответа), или этот ответ вы могли бы сделать в javascript, например, после загрузки страницы он вставляет желаемые кадры iframe.
rogerdpack
34

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

var currentUrl = document.referrer;

и - здесь у вас есть основной URL!

Парпар
источник
Это не сработало в моем случае, так как я думаю, что сам iFrame был сгенерирован динамически или сделал какую-то другую хитрость. Я не получил ответ, который я ожидал, во всяком случае.
Muskie
это должно работать во всех браузерах. Если только в новых браузерах вы не отправляете параметры Sandboxing, но я сомневаюсь, что это так. Это работает независимо от междоменной области.
2013 г.
Если страница внутри iframe перезагружалась через javascript (например window.location.reload(true)), это больше не работает. Тогда referrer - это URL самого iframe.
Мори
20

Для страниц в одном домене и другом поддомене вы можете установить 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

user409021
источник
3
Пожалуйста, примите это как ответ, теперь, когда это возможно и что этот ответ появляется в поиске Google.
Метаграф
17

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

Роберт-Ян Кайпер
источник
После изменений, внесенных в Chrome, теперь это правильный ответ для многих браузеров.
Дэн Аткинсон
Не полный URL, хотя. Только домен
TheMaster
document.location.ancestorOriginsвозвращается undefinedза мной
Мигель Мота
Что касается поддержки браузеров, в частности, по состоянию на июль 2020 года, ancestorOrigins еще не поддерживается в Firefox из-за проблем конфиденциальности. Запрос и обсуждение функции Bugzilla: bugzilla.mozilla.org/show_bug.cgi?id=1085214 . Поддержка браузера: caniuse.com/#search=ancestorOrigins
Колин Мок,
9

Попытайся:

document.referrer

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

Бенджамим Уильям Л. Нунес
источник
2

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

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

Hyzer Deeds
источник
2
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;
user3523340
источник
2
Если вы выходите за пределы iframe, то запускаете скрипт на родительском фрейме, вам не нужно ничего проверять.
Art3mix
1

Я не мог заставить работать предыдущее решение, но я обнаружил, что если я установлю 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];
Павел
источник
1

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

TARKUS
источник
1

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

Дэн
источник
0

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

Гена Мороз
источник
0

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

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

Брюс
источник
-1

Это помогло мне получить доступ к URL-адресу iframe.

window.document.URL
user1503606
источник
-4

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