Changing parent window's URL from IFrame - javascript

I have a situation where I have web apps on two different servers, where App1 contains App2 in an IFrame. Any links in App2 can have target="_parent" attribute, which allow those links to open in the top window. However, I can't find any way to get the same behavior in Javascript. I found this page, which claims that the child frame can call javascript on the parent frame using parent.foo(), but that doesn't seem to work in IE8 or FF3.5. I found this SO question which explains how this security model works. But it seems odd that I can't do in Javascript what I can do with a simple <a> tag. Is there any workaround to this at all? I know about window.postMessage, but (as far as I know) this only works in Firefox.
Example
server1/test.html
<html>
<head>
<script type="text/javascript">
function myCallback(foo) {
alert(foo);
}
</script>
</head>
<body>
<iframe src="http://server2/test2.htm" width="400" height="150"></iframe>
</body></html>
server2/test2.html
<html><body>
<script>
function clickit() {
parent.document.location = "http://www.google.com"; //not allowed
parent.myCallback("http://www.google.com"); //not allowed
}
</script>
<p>This should be in an iFrame!</p>
<p>normal link (works)</p>
<p>javascript link</p>
</body></html>

OK I did more investigation, and it appears that postMessage works in all modern browsers, even IE (with the caveat that IE has a slightly different way of doing it). Here's how I got it to work (tested on WinXP in IE8, FF3.5, Chrome 3.0, Safari 4 beta, Opera 9.64):
server1/test.html
<html>
<head>
<script type="text/javascript">
if(navigator.appName == "Microsoft Internet Explorer")
window.attachEvent("onmessage", receiveMessage);
else
window.addEventListener("message", receiveMessage, false);
function receiveMessage(e) {
if(e.origin == "http://server2") //important for security
if(e.data.indexOf('redirect:') == 0)
document.location = e.data.substr(9);
}
</script>
</head>
<body>
<iframe src="http://server2/test2.htm" width="400" height="150"></iframe>
</body>
</html>
server2/test2.htm
<html><body>
<script>
function clickit() {
parent.postMessage('redirect:http://www.google.com', 'http://server1');
}
</script>
<p>This should be in an iFrame!</p>
<p>normal link</p>
<p>javascript link</p>
</body></html>

A simple thing you can do is:
execute following from JavaScript code of iframe page
top.location = "https://www.google.co.in/";
this will change the location of window's URL to https://www.google.co.in/.
One more thing -This strategy can also be useful when you do not want that any one can inframe your site
just write the above code in document ready part.

No, and for good reason. If you need this, then you must run all communication through one of the two servers; for example, have server1 act as as a proxy for all requests for "server2/test2.html".

If both parent and iframe are on subdomains under the same domain, you may be able to do something with the document.domain property. If both body and iframe are treated as being from the same origin, changing the location should be possible; I haven't tried this myself. Some reading here

If the frames are on the same domain, you should be able to access the parent frame. Otherwise no, it's a security issue.
The only workaround that springs to mind would be to use AJAX to update a file on each of the servers, then check the contents of the opposite file server-side. You could do the same thing using a single database, if you allow connections from external domains.
This is all kind of overkill though, when you could simply pop-up a link in the frame and tell users to click it to continue.

Related

JavaScript access parent window from popup windows

I am trying to code this for hours and still couldn't do it. It keep tell me "Permission Denied".
Here is what I am trying to accomplish. This pretty hard to explain please follow the example below.
For example. domain111.com and domain222.com.
When I am on domain111.com i click on the popup link , it will pop-up the domain111.com/popup.html then it redirect me to domain222.com. On this domain222.com it will redirect to couple pages before it redirect back to domain111.com with the result. I want to send the result from domain111.com to domain111.com.
The process is like below.
Domain111-popup to-->Domain111-redirect-->Domain222-redirect xxx Domain222 pages then redirect to-->-Domain111---SEND to parent window->Domain11
Here is my code.
File name 1.hml on domain111.com
<script type="text/javascript">
function IamParent() {
alert('I am the parent of this window')
}
function PopUP() {
window.open("http://domain222.com/2.htm", 'ALpop').focus();
}
</script>
<body>
<a href="#void(0);" onclick="PopUP();" >Click</a>
</body>
File name 2.html on domain222.com
<head>
<title></title>
<meta http-equiv="refresh" content="1;url=http://domain111.com/3.htm?Result=Yes" />
</head>
Filename 2.htm on domain111.com
<script type="text/javascript">
parent.IamParent(); //execute the function from the same domain111.com/1.htm
</script>
Please don't suggest AJAX or web request because it will not work with this case.
Thanks for reading.
Parent windows in other domains are inaccessible due to a security restriction requirement in the JavaScript engines. This applies to all browsers. It is a cross-site scripting attack prevention that cannot be disabled.

How to determine if the location of the iframe has changed?

I have got an iframe that displays a form from an external site,once the form is submitted it is redirected to another page that has got a thankyou message.Is it posiible to know from the iframe if the location of src webpage has changed? i hope im making some sense...
i got this code which will do the job for me from some website,its working while im in their website but when i try to do it locally im getting Access Denied javascript error....
<html>
<body>
<script language="JavaScript">
function myLocation() {
alert(document.all.myFrame.contentWindow.location);
}
</script>
<iframe id="myFrame" src="http://www.java2s.com" style="width:200;">
</iframe>
<br>
<button onclick="myLocation();">Location of Frame</button>
</body>
</html>
thank you
You may want to use the onLoad event, as in the following example:
<iframe src="http://www.google.com/" onLoad="alert('Test');"></iframe>
The alert will pop-up whenever the location within the iframe has changed. The only problem with this technique is that it may not work with some older browsers like IE5 and early Opera. (Source)
UPDATE:
Further to your edit, you are getting the "Access Denied" error because you cannot access the contentWindow.location of a website that is not within the same domain of the parent window. While this is unfortunate for your genuine requirement, this is considered a security restriction to prevent cross-site scripting.
function chkCounter(counterValue) {
var tmp=document.getElementById('txtCounter').value;
document.getElementById('txtCounter').value=tmp+counterValue;
if(document.getElementById('txtCounter').value>1)
{
document.getElementById("btnClose").disabled = false;
}
}
<input align="middle" type="button" onClick="self.close();" value="CLOSE" disabled="true" id="btnClose">
<input type="hidden" id="txtCounter">

Write elements into a child iframe using Javascript or jQuery

I have something like this:
<!doctype html>
<html>
<body>
<iframe id="someFrame"></iframe>
</body>
</html>
And I would like to use jQuery to write elements such that the full equivalent HTML would be like this:
<!doctype html>
<html>
<body>
<iframe id="someFrame">
<!-- inside the iframe's content -->
<!-- <html><body> -->
<div>A</div>
<div>B</div>
<div>C</div>
<!-- </body></html> -->
</iframe>
</body>
</html>
Alternatively, any plain-old-Javascript would be fine.
Thanks.
Edit: After a little more research, it seems I am looking for an IE-equivalent of the contentDocument property of an iframe. "contentDocument" is a W3C standard which FF supports, but IE does not. (surprise surprise)
You can do both, you just have to target differently:
var ifrm = document.getElementById('myIframe');
ifrm = ifrm.contentWindow || ifrm.contentDocument.document || ifrm.contentDocument;
ifrm.document.open();
ifrm.document.write('Hello World!');
ifrm.document.close();
After some research, and a corroborating answer from Mike, I've found this is a solution:
var d = $("#someFrame")[0].contentWindow.document; // contentWindow works in IE7 and FF
d.open(); d.close(); // must open and close document object to start using it!
// now start doing normal jQuery:
$("body", d).append("<div>A</div><div>B</div><div>C</div>");
There are two reliable methods to access the document element inside an iframe:
1. The window.frames property:
var iframeDocument = window.frames['iframeName'].document; // or // var iframeDocument = window.frames[iframeIndex].document;
Demo
2. The contentDocument property:
var iframeDocument = document.getElementById('iframeID').contentDocument; // or // var iframeDocument = document.getElementById('iframeID').contentWindow.document;
Demo
I am going out on a limb here and suggest that the answers proposed so far are not possible.
If this iframe actually has a src="somepage.html" (which you ought to have indicated, and if not, what is the point of using iframe?), then I do not think Jquery can directly manipulate html across frames in all browsers. Based on my experience with this kind of thing, the containing page cannot directly call functions from or make any sort of Javascript contact with the iframe page.
Your "somepage.html" (the page that loads in the iframe) needs to do two things:
Pass some kind of object to the containing page that can be used as a bridge
Have a function to set the HTML as you desired
So for example, somepage.html might look like this:
<!doctype html>
<html>
<head>
<script src="jquery.js">
</script>
<script language=JavaScript>
<!--//
var bridge={
setHtml:function(htm) {
document.body.innerHTML=htm;
}
}
$(function() { parent.setBridge(bridge); });
//--></script>
</head>
<body></body>
</html>
and the containing page might look like this:
<!doctype html>
<html>
<head>
<script src="jquery.js">
</script>
<script language=JavaScript>
<!--//
var bridge;
var setBridge=function(br) {
bridge=br;
bridge.setHtml("<div>A</div><div>B</div><div>C</div>");
}
//-->
</script>
</head>
<body><iframe src="somepage.html"></iframe></body>
</html>
This may appear a bit convoluted but it can be adapted in a number of directions and should work in at least IE, FF, Chrome, and probably Safari and Opera...
I have found this to be cross-browser compatible... a little crossing of previous answers and a bit of trial & error of my own. :)
I'm using this for a download of a report, or, if an error (message) occurs, it's displayed in the iFrame. Most of the users will probably have the iFrame hidden, I'm using it multi-functional.
The thing is I have to clear the contents of the iFrame every time I click the report download button - the user can change parameters and it happens there are no results which then is displayed in the iFrame as a message. If there are results, the iFrame remains empty - because the code below has cleared it and the window.open(...) method generates a Content-Disposition: attachment;filename=... document.
var $frm = $("#reportIFrame");
var $doc = $frm[0].contentWindow ? $frm[0].contentWindow.document : $frm[0].contentDocument;
var $body = $($doc.body);
$body.html(''); // clear iFrame contents <- I'm using this...
$body.append('<i>Writing into the iFrame...</i>'); // use this to write something into the iFrame
window.open(Module.PATH + 'php/getReport.php' + Report.queryData, 'reportIFrame');
I do not have a browser that supports contentDocument but I've coded it this way so I'm leaving it. Maybe someone has older browsers and can post compatibility confirmation/issues?

IFrame content swapping bug?

I have a web page with a number of iframes, including 3rd party iframes like ad sense and various sharing buttons.
In Firefox, I've noticed that occasionally the content of these iframes get swapped, such that you'll get an ad sense ad where another iframe is. It seems completely random where iframe content shows up. It seems it may have something to do with caching.
Does anyone know what causes this, or any steps I can take to prevent this from happening?
In case anyone is looking I was able to track down the bug report:
https://bugzilla.mozilla.org/show_bug.cgi?id=356558
It's been 4 years and it doesn't even look like they have confirmed it.
The workaround described in that Mozilla bug report worked for me:
<iframe src="webpage2.html?var=xxx" id="theframe"></iframe>
<script>
var _theframe = document.getElementById("theframe");
_theframe.contentWindow.location.href = _theframe.src;
</script>
One plausible answer is that two iframes have the same name. I've experienced this several times in conkeror (firefox based), and every time it's been a name conflict.
I've been wrestling with this for awhile now. The problem is with firefox and the way that it caches iframe content. It's not random either. There is nothing to do to prevent this short of not using iframes.
You can reload the iframes onload using something like:
var reloadIframes = function () {
var a = window.frames, b = a.length
while (b--) {
a[b].src = a[b].src;
}
}
In the case of ads it will cause double impressions which will violate you contract.
An easy way to replicate the issue is create 3 html files.
<!--frame1.html-->
<html>
<body>
<h3>frame one</h3>
</body>
</html>
<!--frame2.html-->
<html>
<body>
<h3>frame two</h3>
</body>
</html>
<!--index.html-->
<html>
<body>
<iframe src="frame1.html"></iframe>
<iframe src="frame2.html"></iframe>
</body>
</html>
Open in firefox. Then switch frame one and frame two.
<!--index.html-->
<html>
<body>
<iframe src="frame2.html"></iframe>
<iframe src="frame1.html"></iframe>
</body>
</html>
Refresh index.html. The iframes will not be swapped until you clear your cache.
There is a bug in at mozilla but no one is currently working on it.
This problem maybe similar to yours
try to put
window.onload = yourcode;
together with body unload.
i have the tool tip javascript on head segment which contain
window.onload = initTip;
but conflict with my onload iframe
<body onload = "parent.myframe.location='mypage.html'">
my solution :
delete that window.onload = initTip; from head segment, then put them into body.
<body onload = "initTip(); parent.myframe.location='mypage.html'">
it's work with reload button on firefox

Fetching page source

I have the following code in my page
<html>
<head>
<title>testpage</title>
<script language = 'javascript'>function fchange(){alert(document.getElementById("ifrm").value);</script>
</head>
<body>
<iframe id = 'ifrm' src = 'http://www.google.com' width = '700' height='500'></iframe><input type='button' onclick = 'fchange()' value = 'clickhere'>
</body>
</html>
From this I click the button and an alert box dispalys undefined. But I need the content or the source of the page ('http://www.google.com'). Please help me to do this.
Thanks in advance...
You can't do this, as it breaks the same-origin policy.
If both pages are on the same domain then you can with do what #Joel suggests, or the slightly more old fashioned:
window.frames['ifrm'].document.body.innerHTML;
You'll need <iframe name="ifrm" ...> for this to work.
If you want the source of the iframe, you would need to access the document object of the iframe.
function fchange()
{
alert(document.getElementById("ifrm").contentWindow.document.body.innerHTML);
}
As mentioned by others, you cannot get the source of an iframe which points to a page outside your domain.
You need to have back-end script for that. I think that's the only way. AJAX would not allow to make a request to other domains for security reasons.

Categories

Resources