Related
I would like to reload an <iframe> using JavaScript. The best way I found until now was set the iframe’s src attribute to itself, but this isn’t very clean. Any ideas?
document.getElementById('some_frame_id').contentWindow.location.reload();
be careful, in Firefox, window.frames[] cannot be indexed by id, but by name or index
document.getElementById('iframeid').src = document.getElementById('iframeid').src
It will reload the iframe, even across domains!
Tested with IE7/8, Firefox and Chrome.
Note: As mentioned by #user85461, this approach doesn't work if the iframe src URL has a hash in it (e.g. http://example.com/#something).
If using jQuery, this seems to work:
$('#your_iframe').attr('src', $('#your_iframe').attr('src'));
Appending an empty string to the src attribute of the iFrame also reloads it automatically.
document.getElementById('id').src += '';
window.frames['frameNameOrIndex'].location.reload();
Because of the same origin policy, this won't work when modifying an iframe pointing to a different domain. If you can target newer browsers, consider using HTML5's Cross-document messaging. You view the browsers that support this feature here: http://caniuse.com/#feat=x-doc-messaging.
If you can't use HTML5 functionality, then you can follow the tricks outlined here: http://softwareas.com/cross-domain-communication-with-iframes. That blog entry also does a good job of defining the problem.
I've just come up against this in chrome and the only thing that worked was removing and replacing the iframe. Example:
$(".iframe_wrapper").find("iframe").remove();
var iframe = $('<iframe src="' + src + '" frameborder="0"></iframe>');
$.find(".iframe_wrapper").append(iframe);
Pretty simple, not covered in the other answers.
Simply replacing the src attribute of the iframe element was not satisfactory in my case because one would see the old content until the new page is loaded. This works better if you want to give instant visual feedback:
var url = iframeEl.src;
iframeEl.src = 'about:blank';
setTimeout(function() {
iframeEl.src = url;
}, 10);
A refinement on yajra's post ... I like the thought, but hate the idea of browser detection.
I rather take ppk's view of using object detection instead of browser detection,
(http://www.quirksmode.org/js/support.html),
because then you're actually testing the capabilities of the browser and acting accordingly, rather than what you think the browser is capable of at that time. Also doesn't require so much ugly browser ID string parsing, and doesn't exclude perfectly capable browsers of which you know nothing about.
So, instead of looking at navigator.AppName, why not do something like this, actually testing for the elements you use? (You could use try {} blocks if you want to get even fancier, but this worked for me.)
function reload_message_frame() {
var frame_id = 'live_message_frame';
if(window.document.getElementById(frame_id).location ) {
window.document.getElementById(frame_id).location.reload(true);
} else if (window.document.getElementById(frame_id).contentWindow.location ) {
window.document.getElementById(frame_id).contentWindow.location.reload(true);
} else if (window.document.getElementById(frame_id).src){
window.document.getElementById(frame_id).src = window.document.getElementById(frame_id).src;
} else {
// fail condition, respond as appropriate, or do nothing
alert("Sorry, unable to reload that frame!");
}
}
This way, you can go try as many different permutations as you like or is necessary, without causing javascript errors, and do something sensible if all else fails. It's a little more work to test for your objects before using them, but, IMO, makes for better and more failsafe code.
Worked for me in IE8, Firefox (15.0.1), Chrome (21.0.1180.89 m), and Opera (12.0.2) on Windows.
Maybe I could do even better by actually testing for the reload function, but that's enough for me right now. :)
for new url
location.assign("http:google.com");
The assign() method loads a new document.
reload
location.reload();
The reload() method is used to reload the current document.
Another solution.
const frame = document.getElementById("my-iframe");
frame.parentNode.replaceChild(frame.cloneNode(), frame);
Now to make this work on chrome 66, try this:
const reloadIframe = (iframeId) => {
const el = document.getElementById(iframeId)
const src = el.src
el.src = ''
setTimeout(() => {
el.src = src
})
}
In IE8 using .Net, setting the iframe.src for the first time is ok,
but setting the iframe.src for the second time is not raising the page_load of the iframed page.
To solve it i used iframe.contentDocument.location.href = "NewUrl.htm".
Discover it when used jQuery thickBox and tried to reopen same page in the thickbox iframe.
Then it just showed the earlier page that was opened.
Use reload for IE and set src for other browsers. (reload does not work on FF)
tested on IE 7,8,9 and Firefox
if(navigator.appName == "Microsoft Internet Explorer"){
window.document.getElementById('iframeId').contentWindow.location.reload(true);
}else {
window.document.getElementById('iframeId').src = window.document.getElementById('iframeId').src;
}
If you using Jquery then there is one line code.
$('#iframeID',window.parent.document).attr('src',$('#iframeID',window.parent.document).attr('src'));
and if you are working with same parent then
$('#iframeID',parent.document).attr('src',$('#iframeID',parent.document).attr('src'));
Using self.location.reload() will reload the iframe.
<iframe src="https://vivekkumar11432.wordpress.com/" width="300" height="300"></iframe>
<br><br>
<input type='button' value="Reload" onclick="self.location.reload();" />
<script type="text/javascript">
top.frames['DetailFrame'].location = top.frames['DetailFrame'].location;
</script>
If all of the above doesn't work for you:
window.location.reload();
This for some reason refreshed my iframe instead of the whole script. Maybe because it is placed in the frame itself, while all those getElemntById solutions work when you try to refresh a frame from another frame?
Or I don't understand this fully and talk gibberish, anyways this worked for me like a charm :)
Have you considered appending to the url a meaningless query string parameter?
<iframe src="myBaseURL.com/something/" />
<script>
var i = document.getElementsById("iframe")[0],
src = i.src,
number = 1;
//For an update
i.src = src + "?ignoreMe=" + number;
number++;
</script>
It won't be seen & if you are aware of the parameter being safe then it should be fine.
Reload from inside Iframe
If your app is inside an Iframe you can refresh it with replacing the location href:
document.location.href = document.location.href
If you tried all of the other suggestions, and couldn't get any of them to work (like I couldn't), here's something you can try that may be useful.
HTML
<a class="refresh-this-frame" rel="#iframe-id-0">Refresh</a>
<iframe src="" id="iframe-id-0"></iframe>
JS
$('.refresh-this-frame').click(function() {
var thisIframe = $(this).attr('rel');
var currentState = $(thisIframe).attr('src');
function removeSrc() {
$(thisIframe).attr('src', '');
}
setTimeout (removeSrc, 100);
function replaceSrc() {
$(thisIframe).attr('src', currentState);
}
setTimeout (replaceSrc, 200);
});
I initially set out to try and save some time with RWD and cross-browser testing. I wanted to create a quick page that housed a bunch of iframes, organized into groups that I would show/hide at will. Logically you'd want to be able to easily and quickly refresh any given frame.
I should note that the project I am working on currently, the one in use in this test-bed, is a one-page site with indexed locations (e.g. index.html#home). That may have had something to do with why I couldn't get any of the other solutions to refresh my particular frame.
Having said that, I know it's not the cleanest thing in the world, but it works for my purposes. Hope this helps someone. Now if only I could figure out how to keep the iframe from scrolling the parent page each time there's animation inside iframe...
EDIT:
I realized that this doesn't "refresh" the iframe like I'd hoped it would. It will reload the iframe's initial source though. Still can't figure out why I couldn't get any of the other options to work..
UPDATE:
The reason I couldn't get any of the other methods to work is because I was testing them in Chrome, and Chrome won't allow you to access an iframe's content (Explanation: Is it likely that future releases of Chrome support contentWindow/contentDocument when iFrame loads a local html file from local html file?) if it doesn't originate from the same location (so far as I understand it). Upon further testing, I can't access contentWindow in FF either.
AMENDED JS
$('.refresh-this-frame').click(function() {
var targetID = $(this).attr('rel');
var targetSrc = $(targetID).attr('src');
var cleanID = targetID.replace("#","");
var chromeTest = ( navigator.userAgent.match(/Chrome/g) ? true : false );
var FFTest = ( navigator.userAgent.match(/Firefox/g) ? true : false );
if (chromeTest == true) {
function removeSrc() {
$(targetID).attr('src', '');
}
setTimeout (removeSrc, 100);
function replaceSrc() {
$(targetID).attr('src', targetSrc);
}
setTimeout (replaceSrc, 200);
}
if (FFTest == true) {
function removeSrc() {
$(targetID).attr('src', '');
}
setTimeout (removeSrc, 100);
function replaceSrc() {
$(targetID).attr('src', targetSrc);
}
setTimeout (replaceSrc, 200);
}
if (chromeTest == false && FFTest == false) {
var targetLoc = (document.getElementById(cleanID).contentWindow.location).toString();
function removeSrc() {
$(targetID).attr('src', '');
}
setTimeout (removeSrc, 100);
function replaceSrc2() {
$(targetID).attr('src', targetLoc);
}
setTimeout (replaceSrc2, 200);
}
});
For debugging purposes one could open the console, change the execution context to the frame that he wants refreshed, and do document.location.reload()
I had a problem with this because I didnt use a timeout to give the page time to update, I set the src to '', and then set it back to the original url, but nothing happened:
function reload() {
document.getElementById('iframe').src = '';
document.getElementById('iframe').src = url;
}
but it didnt reload the site, because it is single threaded, the first change doesnt do anything, because that function is still taking up the thread, and then it sets it back to the original url, and I guess chrome doesnt reload because preformance or whatever, so you need to do:
function setBack() {
document.getElementById('iframe').src = url;
}
function reload() {
document.getElementById('iframe').src = '';
setTimeout(setBack,100);
}
if the setTimeout time is too short, it doesnt work, so if its not working, try set it to 500 or something and see if it works then.
this was in the latest version of chrome at the time of writing this.
This way avoids adding history to some browsers (an unneeded overhead). In the body section put:
<div id='IF'>
<iframe src='https://www.wolframalpha.com/input?i=Memphis%20TN%20Temperature'
style="width:5in; height:6in" // or whatever you want in your Iframe
title'Temperature'></iframe>
</div>
Then in some JAVASCRIPT you may have a function like:
function UPdate() { // Iframe
T1=document.getElementById('IF')
T2=T1.innerHTML
T1.innerHTML=T2
}
I would like to reload an <iframe> using JavaScript. The best way I found until now was set the iframe’s src attribute to itself, but this isn’t very clean. Any ideas?
document.getElementById('some_frame_id').contentWindow.location.reload();
be careful, in Firefox, window.frames[] cannot be indexed by id, but by name or index
document.getElementById('iframeid').src = document.getElementById('iframeid').src
It will reload the iframe, even across domains!
Tested with IE7/8, Firefox and Chrome.
Note: As mentioned by #user85461, this approach doesn't work if the iframe src URL has a hash in it (e.g. http://example.com/#something).
If using jQuery, this seems to work:
$('#your_iframe').attr('src', $('#your_iframe').attr('src'));
Appending an empty string to the src attribute of the iFrame also reloads it automatically.
document.getElementById('id').src += '';
window.frames['frameNameOrIndex'].location.reload();
Because of the same origin policy, this won't work when modifying an iframe pointing to a different domain. If you can target newer browsers, consider using HTML5's Cross-document messaging. You view the browsers that support this feature here: http://caniuse.com/#feat=x-doc-messaging.
If you can't use HTML5 functionality, then you can follow the tricks outlined here: http://softwareas.com/cross-domain-communication-with-iframes. That blog entry also does a good job of defining the problem.
I've just come up against this in chrome and the only thing that worked was removing and replacing the iframe. Example:
$(".iframe_wrapper").find("iframe").remove();
var iframe = $('<iframe src="' + src + '" frameborder="0"></iframe>');
$.find(".iframe_wrapper").append(iframe);
Pretty simple, not covered in the other answers.
Simply replacing the src attribute of the iframe element was not satisfactory in my case because one would see the old content until the new page is loaded. This works better if you want to give instant visual feedback:
var url = iframeEl.src;
iframeEl.src = 'about:blank';
setTimeout(function() {
iframeEl.src = url;
}, 10);
A refinement on yajra's post ... I like the thought, but hate the idea of browser detection.
I rather take ppk's view of using object detection instead of browser detection,
(http://www.quirksmode.org/js/support.html),
because then you're actually testing the capabilities of the browser and acting accordingly, rather than what you think the browser is capable of at that time. Also doesn't require so much ugly browser ID string parsing, and doesn't exclude perfectly capable browsers of which you know nothing about.
So, instead of looking at navigator.AppName, why not do something like this, actually testing for the elements you use? (You could use try {} blocks if you want to get even fancier, but this worked for me.)
function reload_message_frame() {
var frame_id = 'live_message_frame';
if(window.document.getElementById(frame_id).location ) {
window.document.getElementById(frame_id).location.reload(true);
} else if (window.document.getElementById(frame_id).contentWindow.location ) {
window.document.getElementById(frame_id).contentWindow.location.reload(true);
} else if (window.document.getElementById(frame_id).src){
window.document.getElementById(frame_id).src = window.document.getElementById(frame_id).src;
} else {
// fail condition, respond as appropriate, or do nothing
alert("Sorry, unable to reload that frame!");
}
}
This way, you can go try as many different permutations as you like or is necessary, without causing javascript errors, and do something sensible if all else fails. It's a little more work to test for your objects before using them, but, IMO, makes for better and more failsafe code.
Worked for me in IE8, Firefox (15.0.1), Chrome (21.0.1180.89 m), and Opera (12.0.2) on Windows.
Maybe I could do even better by actually testing for the reload function, but that's enough for me right now. :)
for new url
location.assign("http:google.com");
The assign() method loads a new document.
reload
location.reload();
The reload() method is used to reload the current document.
Another solution.
const frame = document.getElementById("my-iframe");
frame.parentNode.replaceChild(frame.cloneNode(), frame);
Now to make this work on chrome 66, try this:
const reloadIframe = (iframeId) => {
const el = document.getElementById(iframeId)
const src = el.src
el.src = ''
setTimeout(() => {
el.src = src
})
}
In IE8 using .Net, setting the iframe.src for the first time is ok,
but setting the iframe.src for the second time is not raising the page_load of the iframed page.
To solve it i used iframe.contentDocument.location.href = "NewUrl.htm".
Discover it when used jQuery thickBox and tried to reopen same page in the thickbox iframe.
Then it just showed the earlier page that was opened.
Use reload for IE and set src for other browsers. (reload does not work on FF)
tested on IE 7,8,9 and Firefox
if(navigator.appName == "Microsoft Internet Explorer"){
window.document.getElementById('iframeId').contentWindow.location.reload(true);
}else {
window.document.getElementById('iframeId').src = window.document.getElementById('iframeId').src;
}
If you using Jquery then there is one line code.
$('#iframeID',window.parent.document).attr('src',$('#iframeID',window.parent.document).attr('src'));
and if you are working with same parent then
$('#iframeID',parent.document).attr('src',$('#iframeID',parent.document).attr('src'));
Using self.location.reload() will reload the iframe.
<iframe src="https://vivekkumar11432.wordpress.com/" width="300" height="300"></iframe>
<br><br>
<input type='button' value="Reload" onclick="self.location.reload();" />
<script type="text/javascript">
top.frames['DetailFrame'].location = top.frames['DetailFrame'].location;
</script>
If all of the above doesn't work for you:
window.location.reload();
This for some reason refreshed my iframe instead of the whole script. Maybe because it is placed in the frame itself, while all those getElemntById solutions work when you try to refresh a frame from another frame?
Or I don't understand this fully and talk gibberish, anyways this worked for me like a charm :)
Have you considered appending to the url a meaningless query string parameter?
<iframe src="myBaseURL.com/something/" />
<script>
var i = document.getElementsById("iframe")[0],
src = i.src,
number = 1;
//For an update
i.src = src + "?ignoreMe=" + number;
number++;
</script>
It won't be seen & if you are aware of the parameter being safe then it should be fine.
Reload from inside Iframe
If your app is inside an Iframe you can refresh it with replacing the location href:
document.location.href = document.location.href
If you tried all of the other suggestions, and couldn't get any of them to work (like I couldn't), here's something you can try that may be useful.
HTML
<a class="refresh-this-frame" rel="#iframe-id-0">Refresh</a>
<iframe src="" id="iframe-id-0"></iframe>
JS
$('.refresh-this-frame').click(function() {
var thisIframe = $(this).attr('rel');
var currentState = $(thisIframe).attr('src');
function removeSrc() {
$(thisIframe).attr('src', '');
}
setTimeout (removeSrc, 100);
function replaceSrc() {
$(thisIframe).attr('src', currentState);
}
setTimeout (replaceSrc, 200);
});
I initially set out to try and save some time with RWD and cross-browser testing. I wanted to create a quick page that housed a bunch of iframes, organized into groups that I would show/hide at will. Logically you'd want to be able to easily and quickly refresh any given frame.
I should note that the project I am working on currently, the one in use in this test-bed, is a one-page site with indexed locations (e.g. index.html#home). That may have had something to do with why I couldn't get any of the other solutions to refresh my particular frame.
Having said that, I know it's not the cleanest thing in the world, but it works for my purposes. Hope this helps someone. Now if only I could figure out how to keep the iframe from scrolling the parent page each time there's animation inside iframe...
EDIT:
I realized that this doesn't "refresh" the iframe like I'd hoped it would. It will reload the iframe's initial source though. Still can't figure out why I couldn't get any of the other options to work..
UPDATE:
The reason I couldn't get any of the other methods to work is because I was testing them in Chrome, and Chrome won't allow you to access an iframe's content (Explanation: Is it likely that future releases of Chrome support contentWindow/contentDocument when iFrame loads a local html file from local html file?) if it doesn't originate from the same location (so far as I understand it). Upon further testing, I can't access contentWindow in FF either.
AMENDED JS
$('.refresh-this-frame').click(function() {
var targetID = $(this).attr('rel');
var targetSrc = $(targetID).attr('src');
var cleanID = targetID.replace("#","");
var chromeTest = ( navigator.userAgent.match(/Chrome/g) ? true : false );
var FFTest = ( navigator.userAgent.match(/Firefox/g) ? true : false );
if (chromeTest == true) {
function removeSrc() {
$(targetID).attr('src', '');
}
setTimeout (removeSrc, 100);
function replaceSrc() {
$(targetID).attr('src', targetSrc);
}
setTimeout (replaceSrc, 200);
}
if (FFTest == true) {
function removeSrc() {
$(targetID).attr('src', '');
}
setTimeout (removeSrc, 100);
function replaceSrc() {
$(targetID).attr('src', targetSrc);
}
setTimeout (replaceSrc, 200);
}
if (chromeTest == false && FFTest == false) {
var targetLoc = (document.getElementById(cleanID).contentWindow.location).toString();
function removeSrc() {
$(targetID).attr('src', '');
}
setTimeout (removeSrc, 100);
function replaceSrc2() {
$(targetID).attr('src', targetLoc);
}
setTimeout (replaceSrc2, 200);
}
});
For debugging purposes one could open the console, change the execution context to the frame that he wants refreshed, and do document.location.reload()
I had a problem with this because I didnt use a timeout to give the page time to update, I set the src to '', and then set it back to the original url, but nothing happened:
function reload() {
document.getElementById('iframe').src = '';
document.getElementById('iframe').src = url;
}
but it didnt reload the site, because it is single threaded, the first change doesnt do anything, because that function is still taking up the thread, and then it sets it back to the original url, and I guess chrome doesnt reload because preformance or whatever, so you need to do:
function setBack() {
document.getElementById('iframe').src = url;
}
function reload() {
document.getElementById('iframe').src = '';
setTimeout(setBack,100);
}
if the setTimeout time is too short, it doesnt work, so if its not working, try set it to 500 or something and see if it works then.
this was in the latest version of chrome at the time of writing this.
This way avoids adding history to some browsers (an unneeded overhead). In the body section put:
<div id='IF'>
<iframe src='https://www.wolframalpha.com/input?i=Memphis%20TN%20Temperature'
style="width:5in; height:6in" // or whatever you want in your Iframe
title'Temperature'></iframe>
</div>
Then in some JAVASCRIPT you may have a function like:
function UPdate() { // Iframe
T1=document.getElementById('IF')
T2=T1.innerHTML
T1.innerHTML=T2
}
I'm using IE Edge's emulator mode to test some work and one of the project I work on requires IE8. The emulator is pretty useful to debug some stuff that the original IE8 is doing a good job at blackboxing. I'm trying to find a way around this bug since Microsoft isn't willing to fix it.
The problem is that IE8 emulator hangs on SVG image load. I'm currently using this SVG fallback library which works great on the real IE8 but I was wondering if there is a way to modify events or object prototypes using Javascript to change the behavior of the browsers before it tries to load SVG images when parsing HTML? Is there such a way to solve this issue or should I just live with this bug? I have this dirty workaround which does the trick but I'm hoping to find a more proactive solution.
var fixMySVG = setInterval(function () {
var elements = document.getElementsByTagName('img');
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
element.src = element.src.replace(/^(.+)(\.svg)(\?.)*$/ig, '$1.' + 'png' + '$3');
}
if (document.readyState == 'complete') {
clearInterval(fixMySVG);
}
}, 100);
There is no error, the image is just stuck in an 'uninitialized' state (so I cannot use the onerror event). I'm also unaware of any onbeforeoload event I could use.
Is using interval the only solution?
Edit
I realize there is no perfect solution but to solve basic <img> and backgroundImage style, using interval seems to do an good job without performance hit. On top of that fall back images seems to load faster. I updated my SVG fallback to use interval instead of using onload events which solve both IE8 emulator and the real IE8.
It's a really odd bug, since there is no older-version emulation mode in Edge, just mobile one and user-agent string emulation, which will just allow you "to debug errors caused by browser sniffing", but in no way it is related to some feature non-support.
Using your fallback is one out of many options but there is no "clean" way to do this. On top of that it will not solve SVG images using <object>, <iframe> or <embded> elements, nor inline <svg> elements.
So this doesn't point directly to your issue, which should be fixed by IE team since it's a bug in their browser, but just for the hack, here is a way to change the src of an image before the fetching of the original one starts.
Disclaimer
Once again, this is a hack and should not be used in any production nor development site maybe just for an edge debugging case like yours and for experimentation but that's all !
Note : this will work in modern browsers, including Edge with IE8 user-string Emulation set, but not in the original IE8.
Before the dump
This code should be called in the <head> of your document, preferably at the top-most, since everything that is called before it will be called twice.
Read the comments.
<script id="replaceSrcBeforeLoading">
// We need to set an id to the script tag
// This way we can avoid executing it in a loop
(function replaceSrcBeforeLoading(oldSrc, newSrc) {
// first stop the loading of the document
if ('stop' in window) window.stop();
// IE didn't implemented window.stop();
else if ('execCommand' in document) document.execCommand("Stop");
// clear the document
document.removeChild(document.documentElement);
// the function to rewrite our actual page from the xhr response
var parseResp = function(resp) {
// create a new HTML doc
var doc = document.implementation.createHTMLDocument(document.title);
// set its innerHTML to the response
doc.documentElement.innerHTML = resp;
// search for the image you want to modify
// you may need to tweak it to search for multiple images, or even other elements
var img = doc.documentElement.querySelector('img[src*="' + oldSrc + '"]');
// change its src
img.src = newSrc;
// remove this script so it's not executed in a loop
var thisScript = doc.getElementById('replaceSrcBeforeLoading');
thisScript.parentNode.removeChild(thisScript);
// clone the fetched document
var clone = doc.documentElement.cloneNode(true);
// append it to the original one
document.appendChild(clone);
// search for all script elements
// we need to create new script element in order to get them executed
var scripts = Array.prototype.slice.call(clone.querySelectorAll('script'));
for (var i = 0; i < scripts.length; i++) {
var old = scripts[i];
var script = document.createElement('script');
if (old.src) {
script.src = old.src;
}
if (old.innerHTML) {
script.innerHTML = old.innerHTML;
}
old.parentNode.replaceChild(script, old);
}
}
// the request to fetch our current doc
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && (this.status == 200 || this.status == 0)) {
var resp = this.responseText || this.response;
parseResp(resp);
}
};
xhr.open('GET', location.href);
xhr.send();
})('oldSrc.svg',
'newSrc.svg');
</script>
And a live example which won't work with the IE8 UA string since plnkr.co just doesn't allow this browser on his website :-/
I am writing an iframe based facebook app. Now I want to use the same html page to render the normal website as well as the canvas page within facebook. I want to know if I can determine whether the page has been loaded inside the iframe or directly in the browser?
Browsers can block access to window.top due to same origin policy. IE bugs also take place. Here's the working code:
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
top and self are both window objects (along with parent), so you're seeing if your window is the top window.
When in an iframe on the same origin as the parent, the window.frameElement method returns the element (e.g. iframe or object) in which the window is embedded. Otherwise, if browsing in a top-level context, or if the parent and the child frame have different origins, it will evaluate to null.
window.frameElement
? 'embedded in iframe or object'
: 'not embedded or cross-origin'
This is an HTML Standard with basic support in all modern browsers.
if ( window !== window.parent )
{
// The page is in an iframe
}
else
{
// The page is not in an iframe
}
I'm not sure how this example works for older Web browsers but I use this for IE, Firefox and Chrome without an issue:
var iFrameDetection = (window === window.parent) ? false : true;
RoBorg is correct, but I wanted to add a side note.
In IE7/IE8 when Microsoft added Tabs to their browser they broke one thing that will cause havoc with your JS if you are not careful.
Imagine this page layout:
MainPage.html
IframedPage1.html (named "foo")
IframedPage2.html (named "bar")
IframedPage3.html (named "baz")
Now in frame "baz" you click a link (no target, loads in the "baz" frame) it works fine.
If the page that gets loaded, lets call it special.html, uses JS to check if "it" has a parent frame named "bar" it will return true (expected).
Now lets say that the special.html page when it loads, checks the parent frame (for existence and its name, and if it is "bar" it reloads itself in the bar frame. e.g.
if(window.parent && window.parent.name == 'bar'){
window.parent.location = self.location;
}
So far so good. Now comes the bug.
Lets say instead of clicking on the original link like normal, and loading the special.html page in the "baz" frame, you middle-clicked it or chose to open it in a new Tab.
When that new tab loads (with no parent frames at all!) IE will enter an endless loop of page loading! because IE "copies over" the frame structure in JavaScript such that the new tab DOES have a parent, and that parent HAS the name "bar".
The good news, is that checking:
if(self == top){
//this returns true!
}
in that new tab does return true, and thus you can test for this odd condition.
The accepted answer didn't work for me inside the content script of a Firefox 6.0 Extension (Addon-SDK 1.0): Firefox executes the content script in each: the top-level window and in all iframes.
Inside the content script I get the following results:
(window !== window.top) : false
(window.self !== window.top) : true
The strange thing about this output is that it's always the same regardless whether the code is run inside an iframe or the top-level window.
On the other hand Google Chrome seems to execute my content script only once within the top-level window, so the above wouldn't work at all.
What finally worked for me in a content script in both browsers is this:
console.log(window.frames.length + ':' + parent.frames.length);
Without iframes this prints 0:0, in a top-level window containing one frame it prints 1:1, and in the only iframe of a document it prints 0:1.
This allows my extension to determine in both browsers if there are any iframes present, and additionally in Firefox if it is run inside one of the iframes.
I'm using this:
var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
Use this javascript function as an example on how to accomplish this.
function isNoIframeOrIframeInMyHost() {
// Validation: it must be loaded as the top page, or if it is loaded in an iframe
// then it must be embedded in my own domain.
// Info: IF top.location.href is not accessible THEN it is embedded in an iframe
// and the domains are different.
var myresult = true;
try {
var tophref = top.location.href;
var tophostname = top.location.hostname.toString();
var myhref = location.href;
if (tophref === myhref) {
myresult = true;
} else if (tophostname !== "www.yourdomain.com") {
myresult = false;
}
} catch (error) {
// error is a permission error that top.location.href is not accessible
// (which means parent domain <> iframe domain)!
myresult = false;
}
return myresult;
}
Best-for-now Legacy Browser Frame Breaking Script
The other solutions did not worked for me. This one works on all browsers:
One way to defend against clickjacking is to include a "frame-breaker" script in each page that should not be framed. The following methodology will prevent a webpage from being framed even in legacy browsers, that do not support the X-Frame-Options-Header.
In the document HEAD element, add the following:
<style id="antiClickjack">body{display:none !important;}</style>
First apply an ID to the style element itself:
<script type="text/javascript">
if (self === top) {
var antiClickjack = document.getElementById("antiClickjack");
antiClickjack.parentNode.removeChild(antiClickjack);
} else {
top.location = self.location;
}
</script>
This way, everything can be in the document HEAD and you only need one method/taglib in your API.
Reference: https://www.codemagi.com/blog/post/194
I actually used to check window.parent and it worked for me, but lately window is a cyclic object and always has a parent key, iframe or no iframe.
As the comments suggest hard comparing with window.parent works. Not sure if this will work if iframe is exactly the same webpage as parent.
window === window.parent;
Since you are asking in the context of a facebook app, you might want to consider detecting this at the server when the initial request is made. Facebook will pass along a bunch of querystring data including the fb_sig_user key if it is called from an iframe.
Since you probably need to check and use this data anyway in your app, use it to determine the the appropriate context to render.
function amiLoadedInIFrame() {
try {
// Introduce a new propery in window.top
window.top.dummyAttribute = true;
// If window.dummyAttribute is there.. then window and window.top are same intances
return !window.dummyAttribute;
} catch(e) {
// Exception will be raised when the top is in different domain
return true;
}
}
Following on what #magnoz was saying, here is a code implementation of his answer.
constructor() {
let windowLen = window.frames.length;
let parentLen = parent.frames.length;
if (windowLen == 0 && parentLen >= 1) {
this.isInIframe = true
console.log('Is in Iframe!')
} else {
console.log('Is in main window!')
}
}
It's an ancient piece of code that I've used a few times:
if (parent.location.href == self.location.href) {
window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
If you want to know if the user is accessing your app from facebook page tab or canvas check for the Signed Request. If you don't get it, probably the user is not accessing from facebook.
To make sure confirm the signed_request fields structure and fields content.
With the php-sdk you can get the Signed Request like this:
$signed_request = $facebook->getSignedRequest();
You can read more about Signed Request here:
https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/
and here:
https://developers.facebook.com/docs/reference/login/signed-request/
This ended being the simplest solution for me.
<p id="demofsdfsdfs"></p>
<script>
if(window.self !== window.top) {
//run this code if in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "in frame";
}else{
//run code if not in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "no frame";
}
</script>
if (window.frames.length != parent.frames.length) { page loaded in iframe }
But only if number of iframes differs in your page and page who are loading you in iframe. Make no iframe in your page to have 100% guarantee of result of this code
Write this javascript in each page
if (self == top)
{ window.location = "Home.aspx"; }
Then it will automatically redirects to home page.
I would like to reload an <iframe> using JavaScript. The best way I found until now was set the iframe’s src attribute to itself, but this isn’t very clean. Any ideas?
document.getElementById('some_frame_id').contentWindow.location.reload();
be careful, in Firefox, window.frames[] cannot be indexed by id, but by name or index
document.getElementById('iframeid').src = document.getElementById('iframeid').src
It will reload the iframe, even across domains!
Tested with IE7/8, Firefox and Chrome.
Note: As mentioned by #user85461, this approach doesn't work if the iframe src URL has a hash in it (e.g. http://example.com/#something).
If using jQuery, this seems to work:
$('#your_iframe').attr('src', $('#your_iframe').attr('src'));
Appending an empty string to the src attribute of the iFrame also reloads it automatically.
document.getElementById('id').src += '';
window.frames['frameNameOrIndex'].location.reload();
Because of the same origin policy, this won't work when modifying an iframe pointing to a different domain. If you can target newer browsers, consider using HTML5's Cross-document messaging. You view the browsers that support this feature here: http://caniuse.com/#feat=x-doc-messaging.
If you can't use HTML5 functionality, then you can follow the tricks outlined here: http://softwareas.com/cross-domain-communication-with-iframes. That blog entry also does a good job of defining the problem.
I've just come up against this in chrome and the only thing that worked was removing and replacing the iframe. Example:
$(".iframe_wrapper").find("iframe").remove();
var iframe = $('<iframe src="' + src + '" frameborder="0"></iframe>');
$.find(".iframe_wrapper").append(iframe);
Pretty simple, not covered in the other answers.
Simply replacing the src attribute of the iframe element was not satisfactory in my case because one would see the old content until the new page is loaded. This works better if you want to give instant visual feedback:
var url = iframeEl.src;
iframeEl.src = 'about:blank';
setTimeout(function() {
iframeEl.src = url;
}, 10);
A refinement on yajra's post ... I like the thought, but hate the idea of browser detection.
I rather take ppk's view of using object detection instead of browser detection,
(http://www.quirksmode.org/js/support.html),
because then you're actually testing the capabilities of the browser and acting accordingly, rather than what you think the browser is capable of at that time. Also doesn't require so much ugly browser ID string parsing, and doesn't exclude perfectly capable browsers of which you know nothing about.
So, instead of looking at navigator.AppName, why not do something like this, actually testing for the elements you use? (You could use try {} blocks if you want to get even fancier, but this worked for me.)
function reload_message_frame() {
var frame_id = 'live_message_frame';
if(window.document.getElementById(frame_id).location ) {
window.document.getElementById(frame_id).location.reload(true);
} else if (window.document.getElementById(frame_id).contentWindow.location ) {
window.document.getElementById(frame_id).contentWindow.location.reload(true);
} else if (window.document.getElementById(frame_id).src){
window.document.getElementById(frame_id).src = window.document.getElementById(frame_id).src;
} else {
// fail condition, respond as appropriate, or do nothing
alert("Sorry, unable to reload that frame!");
}
}
This way, you can go try as many different permutations as you like or is necessary, without causing javascript errors, and do something sensible if all else fails. It's a little more work to test for your objects before using them, but, IMO, makes for better and more failsafe code.
Worked for me in IE8, Firefox (15.0.1), Chrome (21.0.1180.89 m), and Opera (12.0.2) on Windows.
Maybe I could do even better by actually testing for the reload function, but that's enough for me right now. :)
for new url
location.assign("http:google.com");
The assign() method loads a new document.
reload
location.reload();
The reload() method is used to reload the current document.
Another solution.
const frame = document.getElementById("my-iframe");
frame.parentNode.replaceChild(frame.cloneNode(), frame);
Now to make this work on chrome 66, try this:
const reloadIframe = (iframeId) => {
const el = document.getElementById(iframeId)
const src = el.src
el.src = ''
setTimeout(() => {
el.src = src
})
}
In IE8 using .Net, setting the iframe.src for the first time is ok,
but setting the iframe.src for the second time is not raising the page_load of the iframed page.
To solve it i used iframe.contentDocument.location.href = "NewUrl.htm".
Discover it when used jQuery thickBox and tried to reopen same page in the thickbox iframe.
Then it just showed the earlier page that was opened.
Use reload for IE and set src for other browsers. (reload does not work on FF)
tested on IE 7,8,9 and Firefox
if(navigator.appName == "Microsoft Internet Explorer"){
window.document.getElementById('iframeId').contentWindow.location.reload(true);
}else {
window.document.getElementById('iframeId').src = window.document.getElementById('iframeId').src;
}
If you using Jquery then there is one line code.
$('#iframeID',window.parent.document).attr('src',$('#iframeID',window.parent.document).attr('src'));
and if you are working with same parent then
$('#iframeID',parent.document).attr('src',$('#iframeID',parent.document).attr('src'));
Using self.location.reload() will reload the iframe.
<iframe src="https://vivekkumar11432.wordpress.com/" width="300" height="300"></iframe>
<br><br>
<input type='button' value="Reload" onclick="self.location.reload();" />
<script type="text/javascript">
top.frames['DetailFrame'].location = top.frames['DetailFrame'].location;
</script>
If all of the above doesn't work for you:
window.location.reload();
This for some reason refreshed my iframe instead of the whole script. Maybe because it is placed in the frame itself, while all those getElemntById solutions work when you try to refresh a frame from another frame?
Or I don't understand this fully and talk gibberish, anyways this worked for me like a charm :)
Have you considered appending to the url a meaningless query string parameter?
<iframe src="myBaseURL.com/something/" />
<script>
var i = document.getElementsById("iframe")[0],
src = i.src,
number = 1;
//For an update
i.src = src + "?ignoreMe=" + number;
number++;
</script>
It won't be seen & if you are aware of the parameter being safe then it should be fine.
Reload from inside Iframe
If your app is inside an Iframe you can refresh it with replacing the location href:
document.location.href = document.location.href
If you tried all of the other suggestions, and couldn't get any of them to work (like I couldn't), here's something you can try that may be useful.
HTML
<a class="refresh-this-frame" rel="#iframe-id-0">Refresh</a>
<iframe src="" id="iframe-id-0"></iframe>
JS
$('.refresh-this-frame').click(function() {
var thisIframe = $(this).attr('rel');
var currentState = $(thisIframe).attr('src');
function removeSrc() {
$(thisIframe).attr('src', '');
}
setTimeout (removeSrc, 100);
function replaceSrc() {
$(thisIframe).attr('src', currentState);
}
setTimeout (replaceSrc, 200);
});
I initially set out to try and save some time with RWD and cross-browser testing. I wanted to create a quick page that housed a bunch of iframes, organized into groups that I would show/hide at will. Logically you'd want to be able to easily and quickly refresh any given frame.
I should note that the project I am working on currently, the one in use in this test-bed, is a one-page site with indexed locations (e.g. index.html#home). That may have had something to do with why I couldn't get any of the other solutions to refresh my particular frame.
Having said that, I know it's not the cleanest thing in the world, but it works for my purposes. Hope this helps someone. Now if only I could figure out how to keep the iframe from scrolling the parent page each time there's animation inside iframe...
EDIT:
I realized that this doesn't "refresh" the iframe like I'd hoped it would. It will reload the iframe's initial source though. Still can't figure out why I couldn't get any of the other options to work..
UPDATE:
The reason I couldn't get any of the other methods to work is because I was testing them in Chrome, and Chrome won't allow you to access an iframe's content (Explanation: Is it likely that future releases of Chrome support contentWindow/contentDocument when iFrame loads a local html file from local html file?) if it doesn't originate from the same location (so far as I understand it). Upon further testing, I can't access contentWindow in FF either.
AMENDED JS
$('.refresh-this-frame').click(function() {
var targetID = $(this).attr('rel');
var targetSrc = $(targetID).attr('src');
var cleanID = targetID.replace("#","");
var chromeTest = ( navigator.userAgent.match(/Chrome/g) ? true : false );
var FFTest = ( navigator.userAgent.match(/Firefox/g) ? true : false );
if (chromeTest == true) {
function removeSrc() {
$(targetID).attr('src', '');
}
setTimeout (removeSrc, 100);
function replaceSrc() {
$(targetID).attr('src', targetSrc);
}
setTimeout (replaceSrc, 200);
}
if (FFTest == true) {
function removeSrc() {
$(targetID).attr('src', '');
}
setTimeout (removeSrc, 100);
function replaceSrc() {
$(targetID).attr('src', targetSrc);
}
setTimeout (replaceSrc, 200);
}
if (chromeTest == false && FFTest == false) {
var targetLoc = (document.getElementById(cleanID).contentWindow.location).toString();
function removeSrc() {
$(targetID).attr('src', '');
}
setTimeout (removeSrc, 100);
function replaceSrc2() {
$(targetID).attr('src', targetLoc);
}
setTimeout (replaceSrc2, 200);
}
});
For debugging purposes one could open the console, change the execution context to the frame that he wants refreshed, and do document.location.reload()
I had a problem with this because I didnt use a timeout to give the page time to update, I set the src to '', and then set it back to the original url, but nothing happened:
function reload() {
document.getElementById('iframe').src = '';
document.getElementById('iframe').src = url;
}
but it didnt reload the site, because it is single threaded, the first change doesnt do anything, because that function is still taking up the thread, and then it sets it back to the original url, and I guess chrome doesnt reload because preformance or whatever, so you need to do:
function setBack() {
document.getElementById('iframe').src = url;
}
function reload() {
document.getElementById('iframe').src = '';
setTimeout(setBack,100);
}
if the setTimeout time is too short, it doesnt work, so if its not working, try set it to 500 or something and see if it works then.
this was in the latest version of chrome at the time of writing this.
This way avoids adding history to some browsers (an unneeded overhead). In the body section put:
<div id='IF'>
<iframe src='https://www.wolframalpha.com/input?i=Memphis%20TN%20Temperature'
style="width:5in; height:6in" // or whatever you want in your Iframe
title'Temperature'></iframe>
</div>
Then in some JAVASCRIPT you may have a function like:
function UPdate() { // Iframe
T1=document.getElementById('IF')
T2=T1.innerHTML
T1.innerHTML=T2
}