[英]<iframe> javascript access parent DOM across domains?
I control the content of an iframe which is embedded in a page from another domain. 我控制嵌入在另一个域的页面中的iframe的内容。 Is there any way for javascript in my iframe to make changes to the parent's DOM?
我的iframe中的javascript是否有任何方法可以更改父级的DOM?
For example, I would like to have my iframed script add a bunch of html elements to the parent DOM. 例如,我想让我的iframed脚本向父DOM添加一堆html元素。 This seems like a pretty tall order - thoughts?
这看起来像一个很高的命令 - 想法?
Edit: There exists a technique called " Fragment ID Messaging " which might be a way to communicate between cross-domain iframes. 编辑:存在一种称为“ 片段ID消息 ”的技术,它可能是跨域iframe之间进行通信的一种方式。
Edit: Also, Firefox 3.5, Opera, Chrome (etc) seem to be adopting the html5 "postMessage" api , which allows secure, cross-domain data transmission between frames, iframes and popups. 编辑:此外,Firefox 3.5,Opera,Chrome(等)似乎采用html5 “postMessage”api ,它允许帧,iframe和弹出窗口之间的安全,跨域数据传输。 It works like an event system.
它就像一个事件系统。 IE8 supports this feature, apparently, which is perhaps a little surprising.
IE8显然支持这个功能,这可能有点令人惊讶。
Summary: No, you can't directly access/edit the DOM of a page from another domain. 摘要:不,您无法直接从其他域访问/编辑页面的DOM。 But you can communicate with it, and it can co-operate to make the changes you want.
但是你可以与它进行交流,它可以合作进行你想要的改变。
It is possible. 有可能的。
You were right to mention postMessage in your edits. 你在编辑中提到postMessage是正确的。 For those looking, there is a great backwards-compatible, javascript-only way to communicate across domains.
对于那些寻找,有一个伟大的向后兼容,javascript唯一的方式跨域通信。 Short, easy code as well.
简短易用的代码。 Perfect solution?
完美解决方案 As long as you can request modifications to the parent and the child:
只要您可以请求修改父母和孩子:
http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/ http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/
Yes you can. 是的你可以。
You can implement window.postMessage to communicate accross iframes and/or windows across domains. 您可以实现window.postMessage来跨域传递iframe和/或窗口。
But you need to do it in an asynchronous way. 但是你需要以异步方式完成它。
If you need it synchronously, you need to implement wrappers around those asynchronous methods. 如果需要同步,则需要围绕这些异步方法实现包装器。
<!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://stackoverflow.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 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>
Here, you would modify the child to send postmessages to parent. 在这里,您可以修改子项以将postmessages发送给父级。 eg in child.htm, you do
例如,在child.htm中,你这样做
window.parent.postMessage("alert(document.location.href); document.location.href = 'http://www.google.com/ncr'", "*");
and in parent, you do (in receiveMessage) eval(evt.data);
在父级中,你做(在receiveMessage中)
eval(evt.data);
Not that using eval is insecure, so you would instead pass an enum, and call the corresponding function that you need to put on the parent page. 并不是说使用eval是不安全的,所以你要传递一个枚举,并调用你需要放在父页面上的相应函数。
I guess you will run to security problems without using a proxy. 我猜你会在不使用代理的情况下遇到安全问题。 Proxies can be very to use.
代理可以非常好用。 You can try one of those:
你可以试试其中一个:
(1) a PHP based proxy (be careful cause there are a lot of ads between useful links) (1)基于PHP的代理 (小心因为有用链接之间有很多广告)
(2) a Apache .htaccess proxy - just create a subdirectory proxy
in your domain and put there a .htaccess
file containing: (2)Apache .htaccess代理 - 只需在您的域中创建一个子目录
proxy
,并在其中放置一个.htaccess
文件,其中包含:
RewriteEngine on
RewriteRule ^(.*)$ http://picasaweb.google.com/$1 [P,L]
Put the other domain name in place of picasaweb.google.com 将其他域名替换为picasaweb.google.com
Personally I prefer using the Apache proxy 我个人更喜欢使用Apache代理
For AJAX, the server could return the header Access-Control-Allow-Origin: *
to allow cross-domain access. 对于AJAX,服务器可以返回标头
Access-Control-Allow-Origin: *
以允许跨域访问。 Maybe it works also for IFRAMEs. 也许它也适用于IFRAME。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.