Как реализовать междоменный URL-доступ из Iframe с использованием Javascript?
Мне нужно получить доступ к URL родительского домена из моего Iframe, который находится в другом домене.
Например, "example.com" - это мой веб-сайт, на котором есть Iframe из другого родительского домена, например "google.com". Здесь мне нужно получить доступ к URL родительского домена с моего example.com. То есть мне нужно получить URL "google.com" в моем домене "example.com". Более того, родительский домен не может быть жестко закодирован.
Я попробовал использовать следующий код:
window.parent.location.href()
но это приводит к ошибке "Отказано в доступе". Как правильно реализовать это для достижения этого?
6 ответов
Вы можете попытаться проверить наличие реферера, который должен быть родительским сайтом, если вы используете iframe.
Вы можете сделать это так:
var href = document.referrer;
Возможно, вы захотите взглянуть на эти вопросы / ответы; они могут дать вам некоторую информацию относительно вашей проблемы:
- междоменный доступ в iframe от дочернего к родительскому
<iframe>
Javascript доступ родительского DOM через домены?- Как получить доступ к родительскому Iframe из JavaScript
Короче говоря: доступ к iframe из другого домена невозможен по соображениям безопасности, что объясняет полученное вами сообщение об ошибке.
На этой же странице политики происхождения в Википедии содержится некоторая информация об этой мере безопасности:
В двух словах, политика разрешает сценариям, работающим на страницах, исходящих с одного и того же сайта, получать доступ к методам и свойствам друг друга без особых ограничений, но запрещает доступ к большинству методов и свойств на страницах разных сайтов.
На стороне клиента должно поддерживаться строгое разделение контента, предоставленного несвязанными сайтами, чтобы предотвратить потерю конфиденциальности или целостности данных.
Вместо того, чтобы использовать реферер, вы можете реализовать window.postMessage
общаться через iframes/windows через домены.
Вы публикуете в window.parent, а затем parent возвращает URL.
Это работает, но требует асинхронной связи.
Вам придется написать синхронную оболочку вокруг асинхронных методов, если вам это нужно синхронно.
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title></title>
<!--
<link rel="shortcut icon" href="/favicon.ico">
<link rel="start" href="http://benalman.com/" title="Home">
<link rel="stylesheet" type="text/css" href="/code/php/multi_file.php?m=benalman_css">
<script type="text/javascript" src="/js/mt.js"></script>
-->
<script type="text/javascript">
// What browsers support the window.postMessage call now?
// IE8 does not allow postMessage across windows/tabs
// FF3+, IE8+, Chrome, Safari(5?), Opera10+
function SendMessage()
{
var win = document.getElementById("ifrmChild").contentWindow;
// http://robertnyman.com/2010/03/18/postmessage-in-html5-to-send-messages-between-windows-and-iframes/
// http://stackru.com/questions/16072902/dom-exception-12-for-window-postmessage
// Specify origin. Should be a domain or a wildcard "*"
if (win == null || !window['postMessage'])
alert("oh crap");
else
win.postMessage("hello", "*");
//alert("lol");
}
function ReceiveMessage(evt) {
var message;
//if (evt.origin !== "http://robertnyman.com")
if (false) {
message = 'You ("' + evt.origin + '") are not worthy';
}
else {
message = 'I got "' + evt.data + '" from "' + evt.origin + '"';
}
var ta = document.getElementById("taRecvMessage");
if (ta == null)
alert(message);
else
document.getElementById("taRecvMessage").innerHTML = message;
//evt.source.postMessage("thanks, got it ;)", event.origin);
} // End Function ReceiveMessage
if (!window['postMessage'])
alert("oh crap");
else {
if (window.addEventListener) {
//alert("standards-compliant");
// For standards-compliant web browsers (ie9+)
window.addEventListener("message", ReceiveMessage, false);
}
else {
//alert("not standards-compliant (ie8)");
window.attachEvent("onmessage", ReceiveMessage);
}
}
</script>
</head>
<body>
<iframe id="ifrmChild" src="child.htm" frameborder="0" width="500" height="200" ></iframe>
<br />
<input type="button" value="Test" onclick="SendMessage();" />
</body>
</html>
Child.htm
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title></title>
<!--
<link rel="shortcut icon" href="/favicon.ico">
<link rel="start" href="http://benalman.com/" title="Home">
<link rel="stylesheet" type="text/css" href="/code/php/multi_file.php?m=benalman_css">
<script type="text/javascript" src="/js/mt.js"></script>
-->
<script type="text/javascript">
/*
// Opera 9 supports document.postMessage()
// document is wrong
window.addEventListener("message", function (e) {
//document.getElementById("test").textContent = ;
alert(
e.domain + " said: " + e.data
);
}, false);
*/
// https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage
// http://ejohn.org/blog/cross-window-messaging/
// http://benalman.com/projects/jquery-postmessage-plugin/
// http://benalman.com/code/projects/jquery-postmessage/docs/files/jquery-ba-postmessage-js.html
// .data – A string holding the message passed from the other window.
// .domain (origin?) – The domain name of the window that sent the message.
// .uri – The full URI for the window that sent the message.
// .source – A reference to the window object of the window that sent the message.
function ReceiveMessage(evt) {
var message;
//if (evt.origin !== "http://robertnyman.com")
if(false)
{
message = 'You ("' + evt.origin + '") are not worthy';
}
else
{
message = 'I got "' + evt.data + '" from "' + evt.origin + '"';
}
//alert(evt.source.location.href)
var ta = document.getElementById("taRecvMessage");
if(ta == null)
alert(message);
else
document.getElementById("taRecvMessage").innerHTML = message;
// http://javascript.info/tutorial/cross-window-messaging-with-postmessage
//evt.source.postMessage("thanks, got it", evt.origin);
evt.source.postMessage("thanks, got it", "*");
} // End Function ReceiveMessage
if (!window['postMessage'])
alert("oh crap");
else {
if (window.addEventListener) {
//alert("standards-compliant");
// For standards-compliant web browsers (ie9+)
window.addEventListener("message", ReceiveMessage, false);
}
else {
//alert("not standards-compliant (ie8)");
window.attachEvent("onmessage", ReceiveMessage);
}
}
</script>
</head>
<body style="background-color: gray;">
<h1>Test</h1>
<textarea id="taRecvMessage" rows="20" cols="20" ></textarea>
</body>
</html>
У вас есть несколько вариантов:
Ограничьте домен (см. Document.domain) как на содержащей странице, так и на странице
iframe
к тому же. Тогда они не будут связаны ограничениями "одного и того же происхождения".Используйте postMessage, который поддерживается всеми браузерами HTML5 для
cross-domain
коммуникации.
Хорошая статья здесь: междоменная связь с iframes
Также вы можете напрямую установить document.domain одинаково в обоих кадрах (даже
document.domain = document.domain;
код имеет смысл, потому что сбрасывает порт на ноль), но этот прием не является универсальным.