<iframe>跨域的JavaScript访问父DOM?
我控制embedded在另一个域的页面中的iframe的内容。 有没有什么办法在我的iframe中的JavaScript来更改父级的DOM?
例如,我想让我的iframed脚本添加一堆html元素到父DOM。 这似乎是一个很高的顺序 – 思想?
编辑:存在一种称为“ 片段ID消息传递 ”的技术,这可能是在跨域iframe之间进行通信的一种方式。
编辑:另外,Firefox 3.5,Opera,Chrome(等)似乎采用html5 “postMessage”api ,它允许帧,iframe和popup窗口之间的安全,跨域数据传输。 它像一个事件系统一样工作。 IE8支持这个function,显然,这可能有点令人惊讶。
总结:不,您不能直接访问/编辑另一个域中的页面的DOM。 但是你可以和它沟通,它可以合作做出你想要的改变。
讨厌这样说,但我很喜欢99%肯定不会因为安全而直接发生。
你可以在这里试试。
BHH
有可能的。
您在编辑中提到了postMessage是正确的。 对于那些看起来,有一个很好的向后兼容,只有JavaScript的方式跨域进行通信。 简短的代码也是如此。 完美解决scheme 只要您可以要求对父母和孩子进行修改:
http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/
是的你可以。
您可以实现window.postMessage跨域跨域的iframe和/或窗口进行通信。
但是你需要以asynchronous的方式来完成。
如果您需要同步,则需要实现这些asynchronous方法的包装。
<!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
<!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>
在这里,你将修改孩子发送postmessages给家长。 例如在child.htm中,你可以
window.parent.postMessage("alert(document.location.href); document.location.href = 'http://www.google.com/ncr'", "*");
并在父母,你(在receiveMessage) eval(evt.data);
不是说使用eval是不安全的,所以你应该传递一个枚举,然后调用你需要放在父页面上的相应函数。
我想你会运行安全问题,而不使用代理。 代理可以很好用。 你可以尝试其中的一个:
(1)基于PHP的代理 (请注意,有用的链接之间有很多广告)
(2)一个Apache .htaccess代理 – 只需在你的域中创build一个子目录proxy
,并在那里放置一个.htaccess
文件,其中包含:
RewriteEngine on RewriteRule ^(.*)$ http://picasaweb.google.com/$1 [P,L]
将其他域名replace为picasaweb.google.com
我个人更喜欢使用Apache代理
对于AJAX,服务器可以返回标题Access-Control-Allow-Origin: *
以允许跨域访问。 也许它也适用于IFRAME。