I have two level parent-child iframe hierarchy in my HTML pages. I want to get an object of parent window document in its child document for some manipulation. I works majorly with Google Chrome.
parent.document gives 'undefined' in Google Chrome, while in Mozilla it works fine. What's the catch?
For reference, please find below the content of the three files demonstrating the issue,
First file: 'one.html'
<html>
<head>
</head>
<body>
<input type="hidden" id="one_1" name="one_1" />
<iframe id="one" name="one" src="two.html">
</body>
</html>
Second file: 'two.html'
<html>
<head>
</head>
<body>
<input type="hidden" id="two_1" name="two_1" />
<iframe id="two" name="two" src="three.html">
</body>
</html>
Third file: 'three.html'
<html>
<head>
<script type="text/javascript">
function callme() {
alert(parent.document)
alert(top.document)
}
</script>
</head>
<body>
<input type="hidden" id="three_1" name="three_1" />
<button id="click" name="click" onclick="return callme()">Click Me</button>
</body>
</html>
Assuming that 'one.html' is opened with Google Chrome, when I click on the 'Click Me' button, two successive alert boxes appears with 'undefined' value. When I open 'one.html' in Mozilla, it gives two 'objectHTMLDocument' valued alert boxes appears.
Please find below the console messages while clicking on 'Click Me' button,
Unsafe JavaScript attempt to access frame with URL file:///C:/Users/user/Desktop/two.html from frame with URL file:///C:/Users/user/Desktop/three.html. Domains, protocols and ports must match.
three.html:6
callme three.html:6
onclick three.html:13
Unsafe JavaScript attempt to access frame with URL file:///C:/Users/user/Desktop/one.html from frame with URL file:///C:/Users/user/Desktop/three.html. Domains, protocols and ports must match.
three.html:7
callme three.html:7
onclick three.html:13
Thanks in advance.
I would inject from top-down as opposed to accessing bottom-up. I would set a variable in an iFrame by selecting it and storing it into a variable like so:
var frame = document.getElementById('one');
And then inject a reference to the parent:
frame.contentWindow.frame_parent_reference = window;
And then perform this in the next child iFrame replacing "one" with "two". That way, by third.html, we don't ask for parent or top, but can do the following:
alert(frame_parent_reference.document);
alert(frame_parent_reference.frame_parent_reference.document);
Perhaps not super elegant but it definitely gives you a lot of control (and you can check if the custom reference exists for security).
Good luck!
Related
I do not get it. I thought that I didi it, and now I cannot do it.
Simple html with an iframe. Indide the iframe is another html. I want to change an image from the main iframe when you access the iframe.
HTML from the main html:
Main html:
<!DOCTYPE HTML>
<html lang="en">
<head></head>
<body>
<img id="logo" src="../img/fpdfilms-logo-home.png" />
<iframe id="fondo" name="main" src="test.html"></iframe>
</body>
</html>
test.html
<!DOCTYPE HTML>
<html lang="en">
<head></head>
<body>
<a href="#" onclick="change();">Change Picture</p>
<script src="../js/jquery-1.11.2.min.js"></script>
<script type="text/javascript">
function change()
{
var $logo= $('#logo', window.parent.document);
alert("Does it work?");
$logo.attr("src","../img/fpdfilms-logo-director.png");
}
</script>
</body>
</html>
It is supposed to change the picture when you click on the link. But the ALERT is not showing... I've tried different ways and I'm really lost. Is so difficult to achieve this simple change?
Checked your page (chrome 40) and got
SecurityError: Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match.
so I checked in a server (local express) and works fine.
You can refer to this answer as it does what you need with jquery.
how to access iFrame parent page using jquery?
From the above example selecting an element from an iframe in the parent document use
var $parentElement= $('#parentElement', window.parent.document);
I'm trying to read the contents of a document that is loaded via window.open:
<!DOCTYPE html>
<html>
<body>
<button onclick="openWin()">Open "newWindow" and read its content</button>
<script>
var myWindow;
function openWin() {
myWindow = window.open("http://www.google.com/",
"myWindow", "width=400, height=400");
myWindow.opener.document.write(myWindow.document.body.innerHTML);
}
</script>
</body>
</html>
How can I read the contents of a document after loading it via window.open?
I've tried this with setTimeout function but it didn't work.
This is working :
myWindow.opener.document.write("Done!!");
You can't do that if the document you're opening in a new window is from a different domain (for example, yoursite.com opening a new window that loads google.com). This is a security restriction known as same-origin policy. More information: Same-origin policy (MDN).
Hope this clarifies things a bit for you.
It can sometimes pay to try a few things.
My isp recently added a time stamp to their login form which prevented me using my local post form with preloaded name and password.
I looked for ways of downloading their login page and copying the time stamp to my local form. This would have been easy with almost any script except JavaScript.
Frames failed as they use the X-Frame-Option set to 'Deny'.
To my surprise I was able to copy the time stamp to my local form from a pop-up window containing their form. This now works well. The only slight imperfection was having to use a fixed timeout rather than detecting pop-up page fully loaded.
Here is the disguised full solution:
<html>
<head>
<base href='https://www.isp.net'>
<title>isp</title>
</head>
<body onload="w=window.open('login'); setTimeout('document.f.time-stamp.value=w.document.forms[0].time-stamp.value; document.f.submit(); w.close()',2000)">
<form name=f action='login' method=post>
<input type=hidden name='user-name' value='my-name'>
<input type=hidden name='password' value='my-password'>
<input type=hidden name='time-stamp' value=''>
</form>
</body>
</html>
Im using this code to demonstrate the concept on same domains:
Parent:
<html>
<body>
<form>
<input id="details" name="details">
<input type="button" name="choice" onClick="window.open('http://domainB.com/popuppage.html','popuppage','width=850,toolbar=1,resizable=1,scrollbars=yes,height=700,top=100,left=100');" value="Open popup">
</form>
</body>
</html>
And the popup file:
<html>
<head>
</head>
<body>
<SCRIPT LANGUAGE="JavaScript">
<!-- Begin
function sendValue (s){
var selvalue = s.value;
window.opener.document.getElementById('details').value = selvalue;
window.close();
}
// End -->
</script>
<form name="selectform">
<input name="details" value="">
<input type=button value="Copy input to parent opener" onClick="sendValue(this.form.details);">
</form>
</body>
</html>
This works great, but because the popup make a modification of the content of the parent page window.opener.document.getElementById('details').value = selvalue; this will not work on a crossdomain example for security reasons. I dont want to modify content on parent, i just want to communicate a value to the parent script, so i need a listener script on parent to attend for information sent from the popup on close. Is this possible? alternatives?
As Passerby suggested, postMessage (https://developer.mozilla.org/en-US/docs/DOM/window.postMessage) is the ideal solution for what you want to do. Because it doesn't work on older browsers, you'll either have to limit your stuff to newer browsers or employ hacks with iframes and the like to achieve cross-domain communication.
You could run easyXDM in the popup and have it load domainA.com in an iframe, then from that iframe you should be able to access and manipulate the other page on domainA.com that initiated the popup.
script of iframe
<script type="text/javascript" >
var a=5;
</script>
script of parent window
<script type="text/javascript" >
function close()
{
var check=document.getElementById("iframeid").contentDocument.a;
alert(check)
}
</script>
I want to access the variable which is defined inside the iframe from parent. But the above code doesn't work properly can anyone give an idea to implement this.
Using contentWindow instead of contentDocument works for me:
var check = document.getElementById("iframeid").contentWindow.a;
Also, ensure that the domains match and that you are using a webserver to test (I got a protocol warning when testing from the file system).
UPDATE: You're almost definitely better to use the postMessage API.
One method that has always worked reliably for me is for the iFrame to give its parent a reference to its own window when it first loads. The parent can then access all the variables through that reference. This does require that the parent is loaded before the iFrame, but for me that is usually the case.
So in the parent
var iFrameWin;
Then in the iFrame at some point after it has loaded and settled down
parent.iFrameWin = window; //parent now has a ref to the iframe's window
Then, in the parent when it wants a global var contents from the iFrame
alert(iFrameWin.ivar); // shows value if the global 'ivar' in the iFrame
script of iframe:
var a = 5;
window.parent.postMessage(['varA', a], '*'); // put this in some sort of function, ready, or whatever - you can call it multiple times if you need to as the code in the parent is an eventListener
script of parent window:
var b;
// you might want to write these into if statements to make sure that e.data[0] is varA if you have multiple messages coming across
if (typeof window.addEventListener != 'undefined') {
window.addEventListener('message', function(e) {
b = e.data[1];
}, false);
} else if (typeof window.attachEvent != 'undefined') { // this part is for IE8
window.attachEvent('onmessage', function(e) {
b = e.data; // you'll probably have to play around with this part as I can't remember exactly how it comes across in IE8 -- i think it will involve slice() iirc
});
}
Most of my knowledge on this topic comes from Ben Vinegar's talk on Seamless iFrames
This is a cross-domain "okay" method to deal wit this stuff. I'm sure there are some security holes, just as with anything on the web.
See if this works for you:
i created this parent.html page and put an iframe in it with a text input which will show the value passed from iframe window:
<html>
<head>
<title>IFrame Example</title>
<script language="javascript">
function hello(string){
var name=string
document.getElementById('myAnchor').value=name;
}
</script>
</head>
<body>
<iframe namne="iframe" id="iframe_id" src="inputForm.html" height="150" >
</iframe>
Name: <input type="text" id="myAnchor" >
</body>
</html>
and this iframe content page:
<html>
<head>
<title>IFrame Child Example</title>
</head>
<body>
<form name="frm2" >
<h1><font color="#000099">Input Form</font></h1>
<p>Name : </p><input type="text" name="resp" id="input" value=""/>
<input type="button" onclick="parent.hello(this.form.resp.value);" value="Submit" />
</form>
</body>
</html>
clicking the button i get the value in my parent window.
Play with it if you get something with this one.
document.getElementById('ID_OF_IFRAME').document.getElementById('f1')
Note that cross-domain restrictions will still apply.
This is how SharePoint do it when passing argument values from the parent window to the iframe. It's simple, but it works.
<html>
<body>
<iframe id="iframe1"></iframe>
<script type="text/javascript">
var ifr = window.document.getElementById("iframe1");
ifr.dialogArgs = "Hello from the other side.";
ifr.src = "iframeContent.html"
</script>
</body>
</html>
Inside iframeContent.html:
<html>
<body>
<input type="button" value="Click Me!" onclick="alert(window.frameElement.dialogArgs);" />
</body>
</html>
The other way around (accessing ifr.dialogArgs from the parent window after having its value modified by the iframe document) also works.
I have an HTML page that opens another page via JavaScript. When a user clicks a button in the other page, I want to post a message in a DIV of the opening page via JQuery. I cannot put my finger on it, but I cannot seem to get this to work. Here is my opener page
<html>
<head>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
</head>
<body>
<input type="button" onclick="window.open('dialog.html', '_blank', 'height=200, width=300');" value="launch!" />
<div id="testDiv"></div>
</body>
</html>
When the user clicks the "launch!" button, a dialog will appear. The code for the dialog looks like this:
<html>
<head>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
</head>
<body>
<input type="button" onclick="updateOpener()" value="Update Opener" />
<script type="text/javascript">
function updateOpener()
{
var testDiv = window.opener.jQuery("#testDiv");
if (testDiv != null) {
alert("here");
testDiv.html("Updated!");
}
}
</script>
</body>
</html>
Surprisingly, the alert box appears. However, I cannot seem to update the HTML of the DIV in my opening page. Does anyone know how to do this?
You're referencing "confirmDiv". Where is that DIV?
You can't do that if the parent page (the opener) resides on another domain. Otherwise, your code works perfectly.
Also, your != null check is probably not doing what you think it is doing, as the jQuery function never returns null. If you are checking for the existence of an element, you need to do it this way...
var el = $("#myElementId");
if(el.length == 0)
alert('Not found!');
Ummm, it works for me in Firefox 3.0.11, IE8 and Chrome 2... (I.e. the dialog.html button updates the HTML in the opener page to say 'Updated!'.)
Oddly, your example works fine for me in Chrome, IE 8 and FireFox. Do you have any other details?