Принудително Internet Explorer 9 да изпълни javascript, докато анализира страница?

Фон

Работя върху плъгин за адаптивни изображения за CMS, който използвам, и избрах да използвам метода за незабавно задаване на бисквитки, за да кажа на сървъра размерите на екрана на потребителя.

За тези, които не са запознати с това, това означава, че задавате бисквитка в javascript точно в горната част на документа, така че когато браузърът продължи да анализира останалата част от документа, той изпраща вашата бисквитка заедно с всички заявки, които изпраща за изображения.

Това работи в повечето браузъри, с изключение на IE9. Популярното обяснение за това изглежда е, че IE9 просто не задава бисквитки, докато не завърши анализирането на документа, което изглежда като наистина странно поведение. Направих собствено тестване и стигнах до заключението, че бисквитките не са просто някакво специално изключение, това всъщност е начинът, по който IE9 третира javascript - IE9 изглежда не изпълнява никакъв javascript, докато не завърши анализирането на документа.

За съжаление, той изпраща всички свои заявки за външни ресурси, преди да стигне до изпълнението на вградения JS.

Въпрос

Има ли начин да принудите IE9 (и други браузъри, показващи това поведение) да изпълняват javascript, докато документът все още се анализира?

РЕДАКТИРАНЕ

Така че започвам да напредвам, може би това е свързано с IE9 javascript двигателя - който прави фонова компилация. Предполагам, че изчаква, докато получи целия javascript, преди да го компилира. Чудя се дали има малко известен атрибут script-tag за IE, който може да превключва поведението за определен блок. Отивам на лов, ще ви уведомя, ако намеря нещо.

РЕДАКТИРАНЕ 2

Изглежда, че не съм напълно прав относно моите предположения относно начина, по който IE9 работи с javascript. Това е едно от онези нещастни обстоятелства, които научната общност би описала като „дори не грешни“! Като такъв, въпросът по начина, по който го зададох, вече не е полезен, защото разчита на някои погрешни предположения. Въпреки това ще публикувам модифицирания код, който използвах за тестване по-долу:

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);

Изпълнението на test.php ще зареди изображения чрез html и чрез document.write. image.php ще регистрира тези заявки в реда, в който са получени. Ще забележите, че заявките продължават да идват дори когато предупреждението е показано - така че предупреждението не спира изпълнението (въпреки че повечето други браузъри показват подобно поведение). Обратно към квадрат 1!


person Iain Fraser    schedule 16.11.2012    source източник
comment
опитахте ли да настроите бисквитката от страната на сървъра (php)?   -  person Muthu Kumaran    schedule 16.11.2012
comment
@MuthuKumaran Как, за бога, ще знаеш размерите на браузъра на сървъра!!!   -  person epascarello    schedule 16.11.2012
comment
Да, но сървърът не знае размерите на екрана на потребителя - клиентът трябва да зададе бисквитката, за да го каже. И в това се крие проблемът, не мога да задам бисквитката от страна на клиента, докато вече не е твърде късно и браузърът е изпратил всички заявки за изображения.   -  person Iain Fraser    schedule 16.11.2012
comment
@IainFraser, ако използвате PHP, тогава можете да опитате да настроите бисквитката с помощта на setcookie(). Когато HTTP заявката бъде направена, сървърът ще изпрати бисквитката през HTTP заглавката и автоматично ще се зададе във вашия браузър.   -  person Muthu Kumaran    schedule 16.11.2012
comment
@epascarello Не знам, че е просто опит   -  person Muthu Kumaran    schedule 16.11.2012
comment
Въпреки че това няма да даде на сървъра информацията, от която се нуждае, мисля, че разбирам какво се опитвате да кажете. Искате да разберете дали зададената от сървъра бисквитка действително се приема от браузъра, преди да започне да анализира страницата. Самият аз се чудех това, докато тествах, и мога да ви кажа, че е така. Но не можете да го промените от страна на клиента, преди да анализирате страницата, така че все още съм обезпокоен :(   -  person Iain Fraser    schedule 16.11.2012
comment
IE9 appears not to execute any javascript until it has finished parsing the document. - Сигурни ли сте, че не сте обвили кода си в обратно извикване на събитие, като DOMContentLoaded или нещо подобно? Вашето твърдение няма смисъл само по себе си. Ако IE не изпълни JS, докато страницата не приключи анализирането, тогава последователният document.write няма да работи, докато страницата се зарежда, нито ще alert спре изобразяването на страницата.   -  person Fabrício Matté    schedule 16.11.2012
comment
Можете да проверите дали бисквитката вече не е зададена точно и ако не, задайте бисквитката и направете презареждане или пренасочване. Това ще започне страницата отначало с правилната бисквитка. Трябва да се случва само веднъж за размер на браузър/прозорец. Това би било много по-безопасно за браузъра.   -  person jfriend00    schedule 16.11.2012
comment
@FabrícioMatté, знам, че изглежда контраинтуитивно, но клоня към това да е така. Моля, имайте предвид също, че документът е анализиран != документът е готов задължително. Нещо като alert би спряло изобразяването, а не анализирането, до което време заявката за изображения отдавна е изчезнала. Забележка: Не знам това със сигурност, това е само това, което моето проучване показва.   -  person Iain Fraser    schedule 16.11.2012
comment
Разбирам мисълта ти. IE изпращането на заявките преди изпълнението на JS изглежда много възможно.   -  person Fabrício Matté    schedule 16.11.2012


Отговори (3)


Написването на вашите скриптови тагове в документа с document.write() може да реши проблема ви.

Това може да изглежда странно, но забелязах, че това кара DOM действително да се изобразява на екрана след всеки скрипт (което иначе не е така, много досадно, ако се опитате да анимирате лента за напредъка по време на зареждане)

Може също така да реши проблема ви с бисквитките, ако имат същата причина.

person Samuel Rossille    schedule 16.11.2012

Можете да забавите изграждането на вашия DOM. Отидете по пътя на шаблоните:

1) поставете html кода вътре в <script type="text/template" id="someID"></script>. Това ще накара браузъра да има възел на скрипт от тип, който не е javascript. Това ще накара браузъра просто да игнорира съдържанието му, но ще имате достъп до него, като получите вътрешния HTML на възела на скрипта.

2) след като страницата се зареди и готвачите са зададени, можете да прикачите инструмент за обработка на събития document.ready, за да изпълните действителното изграждане на вашия DOM. В този момент анализирането и първоначалното изобразяване ще са приключили, така че очаквам IE да е задал бисквитките досега. Ако не, задействайте изграждането на DOM вътре в setTimout(fn,1);

3) Направете нещо като:

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;
person DanC    schedule 16.11.2012

И така, за да отговоря на въпроса, че този въпрос се е превърнал;

Как да накарате IE9 да зачита бисквитките, които сте задали, когато ги задавате?

И отговорът е откриване на функции. Можем да открием (използвайки старомодни мета тагове) дали даден браузър поддържа или не незабавна настройка на бисквитки и ако не, презареждаме страницата възможно най-скоро (преди да загубим твърде много време).

Кодът

<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>

И едно по-пълно и разпространено решение в моя блог тук:

http://iain-fraser.com/2012/11/cookie-based-responsive-images-that-work-in-ie9/

Ще актуализирам публикацията след уикенда - просто трябваше да сваля всичко, докато беше още прясно. Разбира се, ако го доразвия, ще актуализирам SO съответно.

person Iain Fraser    schedule 16.11.2012