3

看来HEAD我通过 jQuery 的$.ajax({...});方法发送的请求正在返回给定资源的内容(至少在 Firefox 中...... IE 似乎正常运行),而不仅仅是标题。我试图仅捕获Content-Lengthheader 属性,以在图像预加载器中使用,尽管似乎仅通过查询Content-Length,它就下载了内容本身。

这里的操作顺序是:

  • 使用 CSS 查找给定页面中的所有元素,并使用 URLbackground-image填充数组 ( )。imageTemp
  • 对于每个图像 URL,执行 AjaxHEAD请求,以获取URLContent-Length并将其添加到bytesTotal数组 ( imageData) 中,并使用 URL 和该图像的Content-Length.
    • 同时,启动一个setInterval事件处理程序来定期检查是否所有的 AjaxHEAD请求都已完成。
  • 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);

这与我通过 Javascript/jQuery 在 Ajax HEAD 请求中提出的问题直接相关,但它肯定不是重复的,因为该问题已从先前解决的问题扩展而来。

4

2 回答 2

2

我鼓励您设置Fiddler(或其他一些 HTTP 数据包嗅探器)并查看实际通过线路的内容 - 发送的确切请求和收到的确切响应。这将帮助您解决问题是在服务器上还是在客户端上。

于 2011-01-17T21:17:18.680 回答
1

好吧,它看起来很奇怪。这个“应该”起作用。

我不能肯定地说这是问题所在,但可能是这样,我来了:

如果您执行 HEAD 请求,服务器本身不应该向您发送比头部数据更多的信息。几乎每一个你可以在那里使用的网络服务器都尊重这一点。

因此,服务器问题的可能性不大。然而,它可能,取决于运行的应用程序。

但是我在许多爬行环境和其他东西中多次看到这个问题,并且一个非常常见的失败点是重定向。

许多内部库遵循重定向(他们应该这样做),但“忘记”了 HEAD 请求。

我曾经查阅过 RFC,但不能完全弄清楚此时应该做什么。

但是非常严格地解释 HEAD 请求应该给你 Location 标头。

但大多数“用户”可能期望重定向背后的任何内容的头部数据。

例如 Zend ZF 直到今天都有这个问题。scrapy 在稍后的版本中修复了它。

抱歉,我不能给你一个更好的答案,但你的代码在这个问题上看起来是正确的,所以它需要一些试错调试......

于 2011-01-17T21:12:16.247 回答