I have some JavaScript code that dynamically injects an iframe in a given HTML page. Unfortunately, in Firefox, and only in Firefox, although the iframe is created from time to time the relevant URL isn't loaded into it.
I know it wasn't loaded because the relevant URL doesn't appear in the Firebug Net tab, and when I inspect the iframe I don't see any expected HTML code in there (when the iframe is on the same domain as the outlying page). I don't see any JavaScript or network errors either.
Here's a code snippet, I've checked all the relevant variables are correct:
var iframe = document.createElement("iframe");
iframe.width = options["w"];
iframe.height = options["h"];
iframe.scrolling = "no";
iframe.marginWidth = 0;
iframe.marginHeight = 0;
iframe.frameBorder = 0;
iframe.style.borderWidth = 0;
if (node.childNodes.length > 0)
node.insertBefore(iframe, node.childNodes[0]);
else
node.appendChild(iframe);
iframe.contentWindow.location = iframeSrc + "?" + querystring;
Here's an example URL that is set for the iframe (the issue also recreates when the URL points to an external server, had to omit the 'http://' at the beginning otherwise I couldn't post the question):
127.0.0.1:8000/widget/iframe/index.html?style=slide-top-to-bottom&culture_code=en_us&c=26&sc=1324&title=Top%20News&caption=Top%20Stories&order=relevance&count=20&w=250&h=300×tamp=true&scrollbar=false&theme=ui-lightness&className=8815455464592103&referrer=http%3A%2F%2F127.0.0.1%3A8000%2Fwidget%2Fbuilder%2Findex.html
Doing some research on the web, I found this unfixed Firefox bug which seems related to this issue:
https://bugzilla.mozilla.org/show_bug.cgi?id=279048
After reading the bug, I tried several solutions none of which solved the issue:
Setting iframe.src instead of iframe.contentWindow.location
Adding a random parameter to the querystring
Adding the '#' symbol with a random number at the end of the URL
Giving the iframe a random name
Does anyone have a workaround for this annoying Firefox bug? Or is the issue I'm describing unrelated to the bug and has a different solution?
What happens if you add this to the bottom of your script?
iframe.contentWindow.location.reload(true);
Perhaps it will stop the need to reload in FF.
EDIT
Fixed the example
Solved the issue, I was looking in the wrong place. The HTML file where this dynamic iframe was loaded had an empty iframe tag that was removed from the DOM, after which the dynamic iframe was injected instead.
Apparently Firefox cached the last URL for this iframe, and loaded it immediately as the external page loaded. I know because I saw the relevant HTML file being loaded twice in the Firebug Net tab rather than once upon the injection.
After I got rid of this empty iframe tag and relied only on the injected iframe, everything started to work well and the issue didn't reproduce anymore. I guess Firefox didn't like handling this scenario, some kind of bug maybe?
Thanks anyway for helping me out, it gave me the inspiration for the right solution :)
Related
I have seen many questions like this but have not found anything that seems to help with my specific situation so I apologize if this question seems repetitive.
I have a site www.foo.com and have an iframe in it. When information I click on an a tag in foo.com a javascript function is called that passes a new image to the iframe to show the user. The communication between iframe and its "parent" seems to work fine on all browsers EXCEPT RANDOM IE8 PAGES. I get the following error message "access is denied" and the browser points to the function that has been activated. Following is a piece of code from the site to see how it works.
the iframe:
<iframe scrolling="no" src="foo.com/bar" id="ifram" name="ifram"></iframe>
the a tag:
The javascript:
if($(this).val() == '242'){
document.getElementById('ifram').style.border='0px';
document.getElementById('ifram').style.background = "url('../product_images/uploaded_images/Flag.jpg')";
document.frames.ifram.document.body.style.backgroundColor="transparent";
This is just a snippet of a code and does not include the whole process of the ajax call to get the image but was not sure if the ajax is part of the issue. I get an undefined error in firefox but the function still fires . I am assuming I would just need to use window.frames for firefox.
Overall, any help on how to resolve this issue would be appreciated. I am wondering if there is a security issue that has to do with browser settings or if its part of how I coded.
Thanks in advance
It's important to note that if your iframe tag is on a page located at http://www.foo.com but the iframe points to http://foo.com it's considered a sandboxing violation and you'll get access denied. Make sure you're pointing to the same domain as your page is on. You can use relative URLs in the iFrame src tag, too, so you can change it to src="bar.php" (without any domain information).
You dont need to use document.frames before document.frames.ifram.document.body.style.backgroundColor = "#ccc";. Just ifram.document.body.style.backgroundColor = "#ccc"; will do.
This bit of code used to work, and now it doesn't:
var url = myurl +'?id=' + id + '&phase=' + phase;
window.location = url;
Using the IE dev toolbar I've verified that url has a valid url, and window.location returns the new url...the only problem is the page does not reload.
Does anyone know of any reasons for window.location to now actually load a new document when it is assigned to?
Use window.location.href = url; instead.
Is your JavaScript running the onclick event from an <input> type="button" or type="submit"?
If your button is type="submit" it won't work unless you stop the submission from executing.
I know this is kind of obvious but I didn't see this in the other comments so I might just add to this thread.
So i just got this same error today, I for some reason couldn't get my page to redirect to google (just for testing purposes). Copied the code directly from another site and it worked, so i tried google.com again - low and behold it didn't work...
I should also mention that i'm trying to redirect a page in an iframe, not the entire webpage.
So I fired up my trusty Max's HTML Beauty++ 2004 and opened my page in that, sure enough it gave me my error:
This content cannot be displayed in a frame
To help protect the security of information you enter into this
website, the publisher of this content does not allow it to be
displayed in a frame.
The code i Used to get that:
window.location = "http://www.google.com";
It looks like browsers don't display this error, instead they just don't redirect you... Kind of confusing :/
I was using jquery, and a similar problem cropped up and I had to resolve it by adding the data-ajax=false attribute to the <a href="... link.
Thanks to #Senad Meskin.
document.location = url;
worked for me. Any reason why window would stop working?
So, I'm trying to find an answer to why this problem is happening; I've fixed the problem, but I want to know why it happened.
TL;DR
Google-provided conversion tracking code that injected an iframe using document.write suddenly caused the page to cease to execute in all versions of Internet Explorer, but was remedied by injecting the same iframe using a non-document.write method.
The Story:
Doubleclick is an advertising network that provides a JavaScript snippet to track conversions from ads.
The snippet they give looks like this:
<SCRIPT language="JavaScript">
var axel = Math.random()+"";
var a = axel * 10000000000000;
document.write('<IFRAME SRC="https://fls.doubleclick.net/activityi;src=143;type=donat01;cat=indir4;ord=1;num='+ a + '?" WIDTH=10 HEIGHT=10 FRAMEBORDER=0></IFRAME>');
</SCRIPT>
<NOSCRIPT>
<IFRAME SRC="https://fls.doubleclick.net/activityi;src=143;type=donat01;cat=indir4;ord=1;num=1?"
WIDTH=1 HEIGHT=1 FRAMEBORDER=0></IFRAME>
</NOSCRIPT>
Now, I know that, for all sorts of reasons, document.write is hazardous and should be avoided. But, Google is giving me this code, so, I figured I could trust it.
It suddenly started breaking all of our pages for all users using Internet Explorer. As in, the page would stop rendering entirely once it hit the document.write. This was crazy: One of the largest third party advertisers on the internet had given me JavaScript that had LITERALLY broken my purchase pages for 25% of my traffic!
As triage, I quickly substituted in the same code using the injection technique found in Google Analytics:
var iframe = document.createElement('iframe');
iframe.src = //the URL;
iframe.width = 0;
iframe.height = 0;
iframe.frameborder = 0;
var ref = document.getElementsByTagName('script')[0];
ref.parentNode.insertBefore(iframe, ref);
This resolved the problem, without actually explaining:
Why does a nearly empty iframe, injected using document.write, break Internet Explorer, but this method above doesn't?
I've solved the problem; it turns out that it had nothing to do with the contents of the <iframe>.
It turns out the page is served by a framework that began using a backend DOM parser that, for reasons likely related to the presence of </ within a <script> tag within the document.write, completely removes the </iframe> closing tag from the generated page, even though it preserves it in the backend. (It's probably trying to enforce ETAGO rules).
The reason I was able to reproduce it was because I was copying the generated document.write code, not the original code, and never noticed the missing </iframe>. (And my "functioning" document.write code didn't have the stripped out </iframe> tag, leading me to believe that the problem was the contents of the iframe.)
As a result, browsers parsed an unclosed <iframe> tag on the page, which Internet Explorer didn't know how to handle, and died part way through the parsing of the iframe (I'm still not totally sure why).
document.write() blocks further page rendering until it finishes. I assume that the remote script was taking a while to load, and thus blocking the rest of the page from loading.
I also assume that Math.Random() function doesn't help matters.
Also...Google's tracking codes scare me...they tend to be ugly hacks of javascript.
There is 2 reasons why the first method should be slow.
document.write() blocks until it is actually performed
the window’s onload event doesn’t fire until all its iframes, and all the resources in these iframes, have fully loaded
Your solution works because the iframe it creates does not request the remote url until after the onload event. Having a set timeout on the first code, you would also get the page to load, then the request to the remote url to fire.
As to why the change of code broke the site, I can not seem to find any speed differences transferring between the two. Maybe it seemed faster because it was cached.
I don't know about the structure of your site, but normally the first script tag is in the <head>. An iframe in the <head> wouldn't be rendered. I'll wager if you did document.body.getElementsByTagName('script')[0] you would probably have similar issues to the one you described above.
Seems you're having a similar problem that I had several months back. The document.write triggers, and overwrites the page. Just use the iframe directly, and everything should be kosher.
I tried replicating your issue but couldn't on IE9.
Either I don't have the right test setup or it seems IE prior to IE 9 had some bug. Firefox had a simialr bug: https://bugzilla.mozilla.org/show_bug.cgi?id=293633
Maybe its a combination of unclosed iframe and something inside the page that's being rendered.
I used the solution stated on this page to resize the iFrame depending on the content:
Resizing an iframe based on content
And it works perfectly, except in Firefox. In Firefox, the other content is cut-off but once you keep on refreshing the page, the browser will slowly reveal the rest of the content. I saw someone replied that this is the solution to the problem:
Use jQuery to get the body height in
framed.html (FF issue, body kept
growing): var height =
$(document.body).height();
However, I don't know where to put that line of code. Do I insert it somewhere within the 3 snippets of scripts on the original solution? If so, where do I put it?
In www.bar.net/framed.html:
Use jQuery to get the body height in framed.html (FF issue, body kept growing):
change following code
// What's the page height?
var height = document.body.scrollHeight;
with
var height = $(document.body).height();
I already solved it. In case somebody else might be encountering the same problem, I used the code on the web page below which is slightly different from the link I gave above:
http://solidgone.org/Set-IFRAME-height-based-on-size-of-remotely-loaded-content
I tried to run a line of code as the following:
document.getElementById('frame0').contentDocument.location.reload(true); to force iframe to refresh or reload but I got the error like "permission denied" in firefox. Does anyone know why? and help to offer a solution? Thanks!
It is probably because of crossdomain issues - looks like your iframes content is from another domain as your mainframe (from which you run your js code). FF is very restrictive concerning crossdomains.
You can't reload a document that comes from a different hostname, due to the Same origin policy, which applies in all browsers.
You would have to remove the iframe from the page and replace it with a new one:
var iframe= document.getElementById('frame0');
var newiframe= document.createElement('iframe');
newiframe.src= iframe.src;
iframe.parentNode.replaceChild(newiframe, iframe);
However this will load the original src of the <iframe>, which won't be the same as the current location if the user has navigated the page since.