Перекрестный домен postMessage, укажите iFrame
Я использую postMessage
для отправки событий из iframe в его родительский документ. У меня есть контроль над обеими сторонами, но контент поступает из двух разных доменов.
![enter image description here]()
Моя простая проблема заключается в том, что я не могу определить iFrame внутри этого родительского метода обратного вызова. Реализация выглядит следующим образом:
В iFrame:
parent.postMessage(JSON.stringify({action: "closeView" }),'*');
В родительском окне:
window.addEventListener('message',function(event) {
if(event.origin !== 'https://example.com')
return;
// Parse message back to json
var messageObject = JSON.parse(event.data);
var source = event.source;
/* this is returning: Window -URL- */
console.log( source );
/* This will throw Permission denied, although this code is inside of "parent" */
console.log(source.parentNode);
},false);
Я хочу идентифицировать некоторый родительский элемент iframe, который (логически) внутри родительского документа.
Когда я пытаюсь использовать event.source.parentNode
или некоторый jQuery для указанного объекта, Firefox говорит, я не могу этого сделать, чтобы предотвратить XSS, ошибка: Error: Permission denied to access property 'parentNode'
Как я могу получить родительский элемент iFrame, который вызвал прослушиватель событий postMessage
?
Ответы
Ответ 1
для этого вы можете использовать имена окон, поскольку они передаются из тега iframe в контекст iframe.
parent doc:
<iframe name=fr2 src="data:text/html,%3Chtml%3E%0A%20%3Cscript%3E%20parent.postMessage%28%7Bname%3A%20window.name%7D%2C%20%22*%22%29%3B%3C/script%3E%0A%3C/html%3E"></iframe>
<iframe name=fr3 src="data:text/html,%3Chtml%3E%0A%20%3Cscript%3E%20parent.postMessage%28%7Bname%3A%20name%7D%2C%20%22*%22%29%3B%3C/script%3E%0A%3C/html%3E"></iframe>
<script>onmessage = function(e){ // use real event handlers in production
alert("from frame: " + e.data.name);
};</script>
iframe doc:
<html>
<script> parent.postMessage({name: name}, "*");</script>
</html>
который предупреждает "fr2", затем "fr3".
вы можете легко использовать имя, которое можно найти, чтобы найти iframe в родительской DOM, используя атрибуты CSS-селекторов.
иллюстративная демонстрация концепции window.name + iframe: http://pagedemos.com/namingframes/
этот мучительно простой подход также невосприимчив к вопросам, возникающим из-за одинаковых URL-адресов iframe.
Ответ 2
Как я понимаю, это может быть попытка
здесь предположим, что ваш основной URL-адрес - www.abc.com\home.php
<body>
<iframe src="www.abc.com\getOtherDomainContent.php?otherUrl=www.xyz.com"/>
</body>
getOtherDomainContent.php в этом файле необходимо написать ajax-вызов, который получает содержимое перекрестного URL-адреса и нажимает этот контент в текущей части тела iframe (getOtherDomainContent.php).
getOtherDomainContent.php
Код:
<html>
<head>
//import jqry lib or other you use.
<script>
$(document).ready({
//getcontent of xyz.com
var otherUrlContent=getAjaxHtml("www.xyz.com");
$("body").html(otherUrlContent);
// further code after content pushed.
//you can easily access "parent.document" and else using parent which will give you all thing you want to do with your main window
});
</script>
</head>
</html>
Ответ 3
Как видно в этой теме: postMessage Source IFrame, можно сравнить каждый iframes contentWindow
с event.source
следующим образом:
/*each(iframe...){ */
frames[i].contentWindow === event.source
Подсказка:
Когда дело доходит до использования кросс-домена и iFrames, у вас нет доступа к атрибуту id
или name
iFrame внутри iFrame, поэтому мы не можем его получить.
Но мне это не очень понравилось. Мое решение на данный момент выглядит следующим образом:
В iFrame:
parent.postMessage(JSON.stringify({action: "closeView", viewUrl: document.URL}),'*');
Update:
docuent.URL
может стать проблемой при использовании запросов или ссылок с местоположением (#anchor), так как ваш текущий url будет отличаться от источника iframe. Итак, вместо document.URL
лучше использовать [location.protocol, '//', location.host, location.pathname].join('')
(есть ли какой-либо метод для получения url без строки запроса в java script)
В родительском документе:
window.addEventListener('message',function(event) {
if(event.origin !== 'https://example.com')
return;
// Parse message back to json
var messageObject = JSON.parse(event.data);
// Get event triggering iFrame
var triggerFrame = $('iframe[src="'+messageObject.viewUrl+'"]');
},false);
Каждое событие должно отправить текущий URL-адрес iFrame в родительский документ. Теперь мы можем сканировать наши документы для iFrame с заданным URL-адресом и работать с ним.
Если кто-то из вас знает лучший способ, напишите ваши ответы.