Кросс-домен postMessage, идентифицировать iFrame
Я использую postMessage
для отправки событий из iframe в родительский документ. Я контролирую обе стороны, но контент поступает из двух разных областей.
моя простая проблема заключается в том, что я не могу определить 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
прослушивателя событий?
3 ответов
для этого можно использовать имена окон, так как они переходят из тега iframe в контекст iframe.
родитель док:
<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 имеют". затем вы можете легко использовать имя attrib для поиска iframe в Родительском DOM с помощью селекторов attrib CSS.
иллюстративная демонстрация окна.имя + концепция iframe:http://pagedemos.com/namingframes/
это больно простой подход также невосприимчив к проблемам, возникающим из тех же URL-кадров.
Как я понимаю, это может быть попробовать здесь предположим, что 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.РНР Код:
<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>
Как видно в этой теме: источник postMessage 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}),'*');
обновление:
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-адресом и работать с ним.
если некоторые из вас знают лучший способ, пожалуйста, опубликуйте свои ответы.