IFrame content swapping bug? - javascript

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

Related

html page disappears after onclick("open()") event

I wrote an html as
html>
<head>
</head>
<body>
<span onclick = "open()">open</span>
<script src= "script.js"></script>
</body>
</html>
and javascript as
function open(){
var id = "10";
}
whenever I click on the open text in the browser the whole page gets wiped out . Is "open" a reserved word in javascript as with any method name it works(screen doesn't get wiped out) . Just wondering what is happening behind the scene. Any information is appreciated.
I actually came across a similar question recently - the reason this is happening is because open() is being interpreted as window.open(). When no parameters are passed into this function, it navigates to a blank window.
You might be able to circumvent this by putting your script in the head, but a better recommendation is to give your function a more meaningful name.
Side note: Not certain if the behavior is the same across browsers, but in Google Chrome, calling open() opens a new tab.
Further reading on the function here: https://developer.mozilla.org/en-US/docs/Web/API/Window/open
as a general rule you will have a lot of conflicts if you program that way - you need to be more modular - use objects/json for namespacing
<html>
<body>
<span onclick = "mylibrary.open()">open</span>
<script src= "script.js"></script>
</body>
</html>
and javascript as
var mylibrary = {
open : function(){
var id = "10";
}
}
roughly ...

Infinite loading with script tag inside iframe

Here is code, stuck with that simple issue which I never have had in past 7 years:
<html>
<body>
<iframe></iframe>
<script>
window.frames[0].document.write('<scr' + 'ipt type="text/javascript" src="//code.jquery.com/jquery-3.0.0.min.js"><\/scr' + 'ipt>');
</script>
</body>
</html>
The problem is that browser's spin wheel continue to circle.
Network console shows all loaded.
If I remove iframe from DOM, or add/change #src attribute - loading stops.
I believe the first answer is the better way, but I'll provide a second answer that is almost identical to your code, but shows how calling document.close() would have also solved your issue.
The issue is that you've started writing to the document's <head> element in the iFrame, but not finished (that's why the page keeps loading). Calling document.close() signals that you've finished writing to the document.
<html>
<body>
<iframe></iframe>
<script>
var doc = window.frames[0].document
doc.write('<scr' + 'ipt type="text/javascript" src="//code.jquery.com/jquery-3.0.0.min.js"><\/scr' + 'ipt>');
doc.close();
</script>
</body>
</html>
Actually, I've just found solution that works if you have control on inner script (doesn't help with loading 3rd party like jQ though).
You should close "current stream" with document.close().
Looks like firefox might have some weirdness around iframes
<html>
<body>
<iframe></iframe>
<script>setTimeout(function(){window.frames[0].document.write("hi");}, 5000);</script>
</body>
</html>
This results in a spinner that starts 5 seconds after page load and doesn't go away (at least on my computer - firefox 47.0)
Try just:
window.frames[0].document.write('<script type="text/javascript" src="//code.jquery.com/jquery-3.0.0.min.js"><\/script>');
I checked on JSbin and it works ok.
Example page
Update:
I think it cannot work because that iframe doesn't even have any document in it. it's just an empty tag until it has a working src and is populated.
See demo
Anyway, this can only work if the content of the iframe is on the same domain (google "cross-origin iframes"). There is a "race" going on here. you want to load jQuery so the page your are loading would use it, but you cannot load any script from the outside of the iframe to the inside until the page has loaded inside the iframe...
I was able to insert the script without the loading issue you describe by defining and appending the element in Javascript, without any loading issues.
<html>
<body>
<iframe id="myFrame"></iframe>
<script>
var jq = document.createElement('script')
jq.type = 'text/javascript'
jq.src = '//code.jquery.com/jquery-3.0.0.min.js'
document.getElementById('myFrame').contentDocument.getElementsByTagName('body')[0].appendChild(jq);
</script>
</body>
</html>
Of course, changing body to head will change where the script loads in the iFrame.
May use the onload
function populateIFrame() {
const str = `<body></body>`;
const idoc = document.getElementById("demo01")
idoc.contentDocument.write(str)
idoc.close();
}
window.onload=populateIFrame

How to avoid flicker while refreshing iframe?

First of all, even if my question is about how to refresh <iframe>'s without flickering, any other suggestions that would solve my problem will be welcome.
Problem: I have a server that publishes a "main" html page. Meanwhile, it takes pictures (say, one per second) and saves them on the HDD. I want the picture to be displayed on the web page and be refreshed.
Solution found: I use a <iframe></iframe> scope where I put another page that contains only the image. Then this second page is refreshed periodically. So, the entire page is not refreshed, only the image frame. The problem is that this solution suffers from a flickering that occurs each time it is refreshed.
Here is the code of the main page (a little compacted):
<!DOCTYPE html><html><head><title>Blabla</title></head>
<body bgcolor="#404040"><h1>WELCOME!...</h1><hr>
<table border="0"><tr height="480"><td width="640">
<!-- RIGHT HERE! -->
<iframe src="image.html" width="640" height="480" frameborder="0"></iframe>
</td></tr></table>
</body></html>
and the second web page is like this:
<!DOCTYPE html><html><head>
<script type="text/javascript">
<!--
function f( t )
{
setTimeout( "location.reload( true );", t );
}
-->
</script>
</head>
<body bgcolor="#000000" onload="JavaScript:f( 1000 );">
<img src="../images/myimage.png" alt="Erreur" height="100%" width="100%"/>
</body>
</html>
I'm a beginner in JavaScript, so I don't pretend this piece of code is good, even passable. Feel free to give me some advice.
Now, is it possible to reload without flickering? I read that the flickers occur while the page is not entirely loaded. I also read about hidden frames switched on and off during load time, etc. But I cannot find a good solution.
Also, I know that some technologies like AJAX exist but I don't know a lot more about them. Feel free to suggest me to use them if it is necessary, I can learn quickly...
EDIT 1: Most Android browsers don't support relative image size like in my example. Use absolute pixel values in place.
Reloading an iframe will always flicker. But you don't need ajax for this either, just a timer and a trick to avoid caching:
<!DOCTYPE html><html><head><title>Blabla</title></head>
<body bgcolor="#404040"><h1>WELCOME!...</h1><hr>
<table border="0"><tr height="480"><td width="640">
<div>
<img id="theimg" src="../images/myimage.png" alt="Erreur" height="100%" width="100%"/>
</div>
</td></tr></table>
<script type="text/javascript">
var theimg = document.getElementById("theimg");
var theurl = "../images/myimage.png";
setInterval(function() {
theimg.src = theurl + '?t=' + new Date().getTime();
}, 1000);
</script>
</body></html>

Changing parent window's URL from IFrame

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.

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