Запрос HEAD, по-видимому, предназначен для передачи ресурса, а не только заголовков

Похоже, что запросы HEAD, которые я отправляю с помощью метода $.ajax({...}); jQuery, возвращают содержимое данного ресурса (по крайней мере, в Firefox... IE работает нормально), а не только заголовки. Я пытаюсь захватить только свойство заголовка Content-Length для использования в предварительном загрузчике изображений, хотя кажется, что, просто запрашивая Content-Length, он загружает сам контент.

Порядок работы здесь таков:

  • Найдите все элементы на данной странице с помощью CSS background-image и заполните массив (imageTemp) URL-адресами.
  • For each image URL, perform an Ajax HEAD request, to obtain the Content-Length and add that to bytesTotal as well as populate the array (imageData) with both the URL and that image's Content-Length.
    • Simultaneously, start a setInterval event handler to periodically check whether or not all of the Ajax HEAD requests have completed.
  • Когда запросы HEAD будут выполнены, начните загружать изображения в объекты Image() из imageData, добавляя связанное значение изображения Content-Length к значению bytesLoaded.\
  • Когда bytesLoaded == bytesTotal изображений будут загружены, и предварительный загрузчик завершится.

Вот мой скрипт на данный момент:

(function($){

    var callbacks = {
        initiate: function(){},
        progress: function(percent){},
        complete: function(){},
    };

    var imageTemp = Array();
    var imageData = Array();
    var imageCurrent = null;
    var intervalId = 0;
    var bytesLoaded = 0;
    var bytesTotal = 0;

    $.preloader = function(arguments){

        for(var arg in arguments){
            callbacks[arg] = arguments[arg];
        }

        callbacks.initiate();
        $('*')
            .each(function(index){
                if($(this).css('background-image') != 'none'){
                    imageTemp.push($(this).css('background-image').slice(5, -2));
                }
            });

        intervalId = window.setInterval(function(e){

            if(imageData.length == imageTemp.length){
                window.clearInterval(intervalId);

                for(var i = 0; i < imageData.length; i++){

                    (function(imageIndex){
                        currentImage = new Image();
                        currentImage.src = imageData[imageIndex][0];
                        currentImage.onload = function(e){
                            bytesLoaded += parseInt(imageData[imageIndex][1]);
                            callbacks.progress(bytesLoaded/bytesTotal);
                            if(bytesLoaded >= bytesTotal){
                                callbacks.complete();
                            }
                        };
                    })(i);

                }

            }

        }, 1);

        for(var i = 0; i < imageTemp.length; i++){
            (function(i){
                $.ajax({
                    type: "HEAD",
                    async: true,
                    url: imageTemp[i],
                    success: function(message, text, response){
                        var bytes = parseInt(response.getResponseHeader('Content-Length'));
                        bytesTotal += bytes;
                        imageData.push([imageTemp[i], bytes]);
                    },
                });
            })(i);
        }

    };

})(jQuery);

Это напрямую связано с моим вопросом в запросе Ajax HEAD через Javascript/jQuery , но это точно не дубликат, так как вопрос расширился от ранее решенного вопроса.


person Dan Lugg    schedule 17.01.2011    source источник
comment
Если запрос выполняется правильно, и вы получаете больше, чем просто заголовок ответа HTTP, не означает ли это, что это проблема сервера? IE может просто игнорировать тело ответа. Что происходит, когда вы нажимаете на свой URL-адрес с помощью wget или curl?   -  person Pointy    schedule 17.01.2011
comment
@Пойнти; Не пробовал, cURL не установлен. Моя единственная причина этого заключается в том, что предварительный загрузчик зависает на initiate до тех пор, пока он полностью не завершится, а затем переходит к complete, выбрасывает 100%, и предварительный загрузчик готов. Прогресса нет. В то время как в IE он работает нормально; по мере загрузки изображений процент увеличивается. Я полагаю, мне придется попробовать cURL или что-то еще. Любые другие идеи?   -  person Dan Lugg    schedule 17.01.2011
comment
Чтобы помочь в отладке, подробно рассмотрите http-запрос. Я рекомендую расширение livehttpheaders для Firefox. Вы должны увидеть что-то вроде HEAD /image.gif, если javascript и браузер работают правильно. Имейте в виду, вы увидите GET /image.gif, если браузер запрашивает изображение самостоятельно (после того, как он нашел элемент ‹img› или правило css и т. д.), поэтому вы можете увидеть оба типа запросов.   -  person goat    schedule 18.01.2011
comment
может быть, я устал, но... как запретить браузеру выполнять настоящий GET-запрос из css?   -  person regilero    schedule 18.01.2011
comment
@regilero, я думаю, что браузеры будут запрашивать внешние ресурсы (например, изображение), определенные в css, как только браузер будет уверен, что правило стиля действительно необходимо применить. Так что либо не давайте ему правило css, либо, возможно, сделайте какой-нибудь трюк с селектором потомков, который не будет соответствовать, пока js не изменит dom.   -  person goat    schedule 18.01.2011
comment
Спасибо крису и регильеро; Используя Firebug, я могу подробно просмотреть ответ, и контент кажется доступным. Кроме того, если я console.log() часть ответа xmlHttp (я забыл, что именно, я немного не смотрел на это) из запроса HEAD, он выгружает необработанные данные изображения. Это говорит мне о том, что Firefox неправильно интерпретирует мой HEAD запрос. Я видел статьи, в которых упоминается, что некоторые методы запросов не реализованы в соответствии со стандартами даже в популярных браузерах. Хотя часто это незначительные детали, возможно, это тот случай, когда проблема оказывает влияние.   -  person Dan Lugg    schedule 19.01.2011
comment
О, и спасибо Pointy :)   -  person Dan Lugg    schedule 19.01.2011


Ответы (2)


Я рекомендую вам установить Fiddler (или другой анализатор HTTP-пакетов) и посмотреть, что на самом деле происходит. провод - точные запросы отправлены и точные ответы получены. Это поможет вам устранить неполадки, связанные с сервером или клиентом.

person Alex Weinstein    schedule 17.01.2011
comment
Спасибо, Алекс; Похоже, это маршрут, который мне придется использовать для отладки. На данный момент я решил отложить завершение в пользу более важных проектов. Браузерная совместимость всей этой идеи на практике в лучшем случае ужасна, имейте в виду, что я не принял много мер предосторожности, я просто хочу, чтобы это работало где-то, прежде чем я буду беспокоиться о совместимости. Я бегло просмотрел Fiddler, он кажется довольно исчерпывающим; скоро заберу :) - person Dan Lugg; 19.01.2011

Ну странно выглядит. Это "должно" работать.

Я не могу точно сказать, что это проблема, но, возможно, это так, поэтому я иду:

Если вы делаете запрос HEAD, сам сервер не должен отправлять вам больше, чем данные головы. Почти каждый веб-сервер, который вы можете получить, соблюдает это.

Так что вероятность проблемы с сервером маловероятна. Однако это возможно, в зависимости от запущенного приложения.

Но я много раз сталкивался с этой проблемой во многих средах сканирования и прочем, и очень распространенной точкой сбоев были перенаправления.

Многие внутренние библиотеки следуют перенаправлениям (как и должны), но «забывают» о запросе HEAD.

Однажды я просмотрел RFC, но не мог понять, что именно нужно делать в этот момент.

Но очень строго интерпретируемый запрос HEAD должен дать вам заголовок Location.

Но большинство «пользователей», вероятно, ожидают, что за перенаправлением стоят главные данные.

Например, Zend ZF имеет эту проблему до сегодняшнего дня. scrapy исправил это в более позднем выпуске.

Извините, я не могу дать вам лучшего ответа, но ваш код выглядит правильно в отношении этой проблемы, поэтому его отладка методом проб и ошибок...

person The Surrican    schedule 17.01.2011
comment
Спасибо, Джо Хопфгартнер; Это не может быть перенаправление, так как я ориентируюсь на статический контент. Кажется, что существует много несоответствий между браузерами для обработки запросов HEAD, независимо от архитектуры сервера. Я полагаю, мне придется продолжать копать, я все еще немного новичок, когда дело доходит до понимания HTTP-запросов на более низком уровне, но я буду работать над этим. Спасибо за информацию :) - person Dan Lugg; 19.01.2011