Force Internet Explorer 9 to execute javascript while parsing page?

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", "rnrnTestResStartrn", 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']."rn", 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!


Writing your script tags to the document with document.write() might solve your issue.

That might seem weird, but I noticed that doing so causes the DOM to be actually rendered to the screen after each script (which is not the case otherwise, very annoying if you try to animate a progress bar during loading)

It might as well solve your cookies issue if they have the same cause.


You can delay the construction of your DOM. Go the 'templates way':

1) put the html code inside a <script type="text/template" id="someID"></script> . This will cause the browser to have a script node of a type that is not javascript. This will cause the browser to simply ignore its contents, but you will have it available to access it by getting the innerHTML of the script node.

2) after the page has lodaded and the cookes are set, you could attach a document.ready event hanlder to execute the actual construction of your DOM. At this point, the parsing and initial render will have finished, so I expect IE to have set the cookies by now. If not, trigger the construction of the DOM inside a setTimout(fn,1);

3) Do something like:

var content = document.getElementById('someID');
var container = document.getElementById('containerID'); // This could be an empty DIV right next to the <script> tag. 
container.innerHTML = content.innerHTML;

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

<script type="text/javascript">
    var c ='resolution='+Math.max(screen.width,screen.height)+("devicePixelRatio" in window ? ","+devicePixelRatio : ",1");
    var cSet = new RegExp(c);

    //If cookies are enabled and our cookie isn't set
    if(navigator.cookieEnabled && !cSet.test(document.cookie))
    {
        //Set the cookie via a meta tag
        document.write('<me'+'ta http-equiv="Set-Cookie" content="'+c+'; path=/" />');

        //If it hasn't been parsed yet
        if(!cSet.test(document.cookie))
        {
            //Reload the page
            document.location.reload();
        }
    }
</script>

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.

链接地址: http://www.djcxy.com/p/43674.html

上一篇: V8 javascript引擎是否有GIL?

下一篇: 强制Internet Explorer 9在解析页面时执行JavaScript?