HEAD 请求似乎是为了传输资源,而不仅仅是标头

发布于 2024-10-12 10:55:15 字数 3209 浏览 2 评论 0原文

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

这里的操作顺序是:

  • 使用 CSS background-image 查找给定页面中的所有元素,并使用 URL 填充数组 (imageTemp)。
  • 对于每个图像 URL,执行 Ajax HEAD 请求,以获取 Content-Length 并将其添加到 bytesTotal 以及填充数组 ( imageData),同时包含 URL 和该图像的 Content-Length
    • 同时启动 setInterval 事件处理程序以定期检查所有 Ajax HEAD 请求是否已完成。
  • HEAD 请求完成后,开始将图像从 imageData 加载到 Image() 对象中,添加关联的图像 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,但它肯定不是重复的,因为该问题是从之前解决的问题扩展而来的。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一杯敬自由 2024-10-19 10:55:15

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

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.

风苍溪 2024-10-19 10:55:15

嗯,看起来很奇怪。这个“应该”有效。

我不能肯定地说这就是问题所在,但也许就是这样,我就这样说:

如果你发出 HEAD 请求,服务器本身不应该向你发送比头数据更多的数据。
几乎所有网络服务器都遵循这一点。

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

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

许多内部库遵循重定向(正如它们应该的那样),但“忘记”了 HEAD 请求。

我曾经查阅过 RFC,但不太清楚此时到底应该做什么。

但非常严格地解释 HEAD 请求应该为您提供 Location 标头。

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

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

抱歉,我无法给您更好的答案,但您的代码在这个问题上看起来是正确的,因此需要进行一些试验和错误调试...

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文