我使用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'
如何获取触发postMessage
事件监听器的iFrame的父元素?
答案 0 :(得分:18)
您可以使用窗口名称,因为它们会从iframe标记传递到iframe上下文。
父文件:
DirectoryIterator
iframe 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>
警告“fr2”,然后“fr3”。 然后,您可以使用attrib CSS选择器轻松使用 name attrib在父DOM中查找iframe。
window.name + iframe概念的说明性演示:http://pagedemos.com/namingframes/
这种痛苦的简单方法也不受同一网址iframes引起的问题的影响。
答案 1 :(得分:5)
根据我的理解,这可能是尝试 这里假设您的主窗口的网址是www.abc.com \ home.php
<body>
<iframe src="www.abc.com\getOtherDomainContent.php?otherUrl=www.xyz.com"/>
</body>
此文件中的getOtherDomainContent.php需要编写一个获取交叉URL内容的ajax调用,并将该内容推送到当前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>
答案 2 :(得分:2)
在此主题中看到:postMessage Source IFrame可以将每个iframe contentWindow
与event.source
进行比较,如下所示:
/*each(iframe...){ */
frames[i].contentWindow === event.source
<强>提示:强>
在跨域使用和iFrame方面,您无法访问iFrame中iFrame的id
或name
属性,因此我们无法获取这些属性。
但我不太喜欢这个。我现在的解决方案如下:
在iFrame中:
parent.postMessage(JSON.stringify({action: "closeView", viewUrl: document.URL}),'*');
<强>更新强>
当您使用查询或带位置的链接(#anchor)时,docuent.URL
可能会成为一个问题,因为您当前的网址将与iframe网格中的网址不同。因此,最好使用document.URL
(is there any method to get url without query string in java script)
[location.protocol, '//', location.host, location.pathname].join('')
在父文档中:
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);
每个事件都必须将当前的iFrame URL发送到父文档。我们现在可以使用给定的URL扫描iFrame的文档并使用它。
如果你们中的一些人知道更好的方式,请发表你的答案。