Wednesday, June 2, 2010

IE iFrame refresh and back button problem

Have you ever noticed that in all IE's, when you refresh a page (or click the back button) the iFrames are automatically populated? This can be a problem if you are trying to pass unique args into the iFrames.

Here's a short example.
parent.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title></title>
</head>
<body>
<div id="content"></div>
<script type="text/javascript" charset="utf-8">
var iFrame = document.createElement('iframe');
var random = Math.random() * 1000;
iFrame.name = random;
iFrame.id = random;
iFrame.src = 'http://path/to/child.html?r=' + random;
document.getElementById('content').appendChild(iFrame);
</script>
</body>
</html>

child.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title></title>
</head>
<body>
<script type="text/javascript" charset="utf-8">
alert(window.location.search);
</script>
</body>
</html>


When you go to parent.html then child.html will alert the random number that was put into it's SRC. When you refresh the page, it will alert the same number! This is because IE does some funky things with browser history. In this case, it thinks it's saving you some trouble by repopulating the exact iFrame that was there before. Really, it's causing a whole lot of trouble!

To trick it, use this
parent.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title></title>
</head>
<body>
<div id="content"></div>
<script type="text/javascript" charset="utf-8">
var iFrame = document.createElement('iframe');
var random = Math.random() * 1000;
iFrame.name = random;
iFrame.id = random;
iFrame.style.display = 'none';
document.getElementById('content').appendChild(iFrame);
iFrame.src = 'http://path/to/child.html?r=' + random;
iFrame.style.display = '';
</script>
</body>
</html>


By not giving the iFrame a src and having it hidden when it's appended, IE will not try to populate it with what it has in the history. Then, immediately after we append it, we can set the src to what we want and display it!

Magic!

1 comment:

feyladil said...

Thanks a lot. That helped me a lot!