Question

It appears that the HEAD requests I'm sending via jQuery's $.ajax({...}); method, are returning the content of the given resource (at least in Firefox... IE appears to function normally), rather than just headers. I'm trying to capture only the Content-Length header property, for use in an image preloader, though it seems that by merely querying for the Content-Length, it's downloaded the content itself.

The order of operation here, is:

  • Find all elements in a given page with CSS background-image, and populate an array (imageTemp) with the URLs.
  • 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.
  • When the HEAD requests have completed, begin loading the images into Image() objects from imageData, adding the associated image Content-Length value to the bytesLoaded value.\
  • When bytesLoaded == bytesTotal images are done loading, and the preloader has completed.

Here is my script as of currently:

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

This is directly associated with my question over at Ajax HEAD request via Javascript/jQuery, but it certainly not a duplicate, as the issue has extended from the previously solved question.

Was it helpful?

Solution

I encourage you to set up Fiddler (or some other HTTP packet sniffer) and see what is actually going through the wire - exact requests sent and exact response received. This will help you troubleshoot whether the problem is on the server or the client.

OTHER TIPS

Well it looks weird. This "should" work.

I cant say for sure this is the problem but maby it is so here I go:

If you do a HEAD request the server itself shouldnt you send you more than the head data. Almost every webserver you can get out there honors this.

So the chances of a server issue is unlikely. However its possible, depending on the application running.

But I have seen this very issue a lot of times in in many crawling environments and stuff, and a very common point of failures were redirects.

A lot of internal libraries follow redirects (as they should) but "forget" about the HEAD request.

I once looked up the RFC but couldn't quite figure out what exactly should be done at this point.

But very strictly interpreted the HEAD request should give you the Location header.

But most "users" probably expect the head data of whatever is behind the redirect.

For example Zend ZF has this issue up til today. scrapy fixed it some later release.

Sorry I can't give you a better answer but your code looks correct regarding this issue so its some trial and error debugging...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top