Background
I am working on a responsive images plugin for a CMS I use and I have chosen to use the immediate set-cookie method to tell the server the dimensions of the user’s screen.
For those not familiar with this, it means you set a cookie in javascript right at the top of the document, so when the browser continues parsing the rest of the document, it sends your cookie along with any requests it sends for images.
This works in most browsers, except for IE9. The popular explanation for this seems to be that IE9 just doesn’t actually set cookies until it finishes parsing the document, which seems like really odd behaviour. I’ve done my own testing and come to the conclusion that cookies aren’t just some special exception, it’s actually the way IE9 treats javascript – IE9 appears not to execute any javascript until it has finished parsing the document.
Unfortunately, it sends off all its requests for external resources before it gets around to executing the inline JS.
Question
Is there a way to force IE9 (and other browsers exhibiting this behaviour) to execute javascript while the document is still being parsed?
EDIT
So I’m starting to make progress, it may be to do with the IE9 javascript engine – which does background compilation. I imagine it waits until it’s got all the javascript before it compiles it. I wonder if there’s a little-known script-tag attribute for IE that can toggle the behaviour for a particular block. Going to go hunting, I’ll let you all know if I find anything.
EDIT 2
Seems I’m not entirely correct about my assumptions about the way IE9 works with javascript. It’s one of those unfortunate circumstances that the scientific community would describe as being “not even wrong”! As such, the question in the way I asked it is no longer useful because it relies on some faulty assumptions. However, I will post the modified code I used for testing below:
test.php
<?php
file_put_contents("log.txt", "\r\n\r\nTestResStart\r\n", FILE_APPEND);
?>
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<img src="image.php?q=1" />
<script type="text/javascript">
document.write('<img src="image.php?q=4-js" />');
alert("HALT!");
document.write('<img src="image.php?q=5-js" />');
</script>
<img src="image.php?q=2" />
<img src="image.php?q=3" />
</body>
</html>
image.php
<?php
session_start();
file_put_contents("log.txt", "image".$_GET['q']."\r\n", FILE_APPEND);
$rImg = ImageCreate(300,50);
$cor = imagecolorallocate($rImg, 225, 225, 225);
$cor = imagecolorallocate($rImg, 0, 0, 0);
imagestring($rImg,2,0,0,$_GET['q'],$cor);
header('Content-type: image/jpeg');
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
imagejpeg($rImg,NULL,100);
Running test.php will load up images through html and through document.write. image.php will log those requests in the order they were received. You will notice that requests continue to come through even when the alert is displayed – so alert doesn’t halt execution (although most other browsers exhibit similar behaviour). Back to square 1!
So, to answer the question that this question has become;
How do you get IE9 to honour cookies you’ve set when you set them?
And the answer is feature detection. We can detect (using old fashioned meta tags) whether or not a browser supports immediate cookie setting and if it doesn’t we reload the page as soon as possible (before we waste too much time).
The code
And a more complete and rambling solution on my blog here:
http://iain-fraser.com/2012/11/cookie-based-responsive-images-that-work-in-ie9/
I’ll be updating the post after the weekend – I just had to get it all down while it was still fresh. Of course, if I develop it further, I’ll update SO accordingly.