通过 Javascript/jQuery 的 Ajax HEAD 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4715223/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 13:44:31  来源:igfitidea点击:

Ajax HEAD request via Javascript/jQuery

javascriptjqueryajaxhttp-headers

提问by Dan Lugg

I seem to be having some issues with making HEADrequests, and preserving the integrity of data in an array.

我似乎在提出HEAD请求和保持数组中数据的完整性方面遇到了一些问题。

Given this snippet:

鉴于此片段:

var imageTemp = Array();

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

I capture the URLs of all background-images on a given page. Now, trying to grab the size of each image via HEADrequests for Content-Length, I use this snippet:

我捕获给定页面上所有背景图像的 URL。现在,尝试通过HEAD请求获取每个图像的大小Content-Length,我使用以下代码段:

var imageData = Array();

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

However, when I dump imageDatavia console.log, I each element (which should be an array containing the URL and the content-length) ends up as [undefined, XXXX]where XXXXis always the size of the last requested Content-Length

但是,当我转储imageDatavia 时console.log,我的每个元素(应该是一个包含 URL 和内容长度的数组)最终作为[undefined, XXXX]whereXXXX始终是最后请求的大小Content-Length

I'm stumped, though it appears to be a timing/scoping issue. Do I have a sort of race-condition occuring here?

我很难过,虽然这似乎是一个时间/范围问题。我这里发生了某种竞争条件吗?

回答by tvanfosson

The problem is that the single variables iand ajaxSizeRequestbeing captured by the callback function are the same variables for all instances of the callback function. I think if you call a function and pass the index variable to it and, at the same time, scope the request variable locally to the function itselfuse the response parameter of the done handler, you should end up with independent variables captured by the callback. It should then reference each array element and each response variable correctly.

问题在于,回调函数捕获的单个变量iajaxSizeRequest回调函数的所有实例都是相同的变量。我认为如果你调用一个函数并将 index 变量传递给它,同时使用 done 处理程序的响应参数将请求变量本地范围限定为函数本身,你应该最终得到回调捕获的独立变量. 然后它应该正确引用每个数组元素和每个响应变量。

var imageData = Array();

for(var i = 0; i < imageTemp.length; i++){
    updateImageData( i );
}

function updateImageData( i )
    $.ajax({
        type: "HEAD",
        async: true,
        url: imageTemp[i],
    }).done(function(message,text,jqXHR){
        imageData.push([imageTemp[i], jqXHR.getResponseHeader('Content-Length')]);
    });
}

回答by davin

looks like your iisnt properly closed-in

看起来你i没有完全封闭

in addition, you can't use ajaxSizeRequestbecause it too is pointing to just one request (probably the last, because the loop will execute very fast)

此外,您不能使用,ajaxSizeRequest因为它也只指向一个请求(可能是最后一个,因为循环执行速度非常快)

just wrap your successcallback function as follows, changing the reference to ajaxSizeRequest:

只需success按如下方式包装您的回调函数,将引用更改为ajaxSizeRequest

success: (function(i){
   return function(data,status,xhr){
     imageData.push([imageTemp[i], xhr.getResponseHeader('Content-Length')]);
   };
})(i)

回答by Josiah Ruddell

You can scope I like so:

你可以把我喜欢的范围定为:

success: function(i){
    return function(message){
        imageData.push([imageTemp[i], ajaxSizeRequest.getResponseHeader('Content-Length')]);
    }
}(i)

回答by SLaks

You have a single ivariable which is shared by all of the callbacks.
Since AJAX is asynchronous, all of the callbacks run after your loop is finished, and they all get the same i.

您有一个i由所有回调共享的变量。
由于 AJAX 是异步的,所有回调在循环完成后运行,并且它们都得到相同的i.

To fix this, you need to move the AJAX call into a separate function that takes ias a parameter.
Thus, each callback will get a separate iparameter.

要解决此问题,您需要将 AJAX 调用移动到一个单独的函数中,该函数将其i作为参数。
因此,每个回调将获得一个单独的i参数。

回答by Coffee

If anyone still having trouble with this, and since this post is, like, 5 years-old already, here's a more 'modern' version of the answer: just use letinstead of varin the original post's forloop.

如果有人仍然对此有疑问,并且由于这篇文章已经 5 岁了,这里有一个更“现代”的答案版本:只需使用let而不是var在原始帖子的for循环中。

Info: Is there any reason to use the “var” keyword in ES6?and: MDN - Let syntax

信息:是否有理由在 ES6 中使用“var”关键字?和:MDN - Let 语法