通过Javascript / jQuery的Ajax HEAD请求

我似乎在制作HEAD请求时遇到了一些问题,并保留了数组中数据的完整性。

鉴于此片段:

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

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

 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')]); } }); } 

但是,当我通过console.log dump imageData时,每个元素(应该是一个包含URL和内容长度的数组)结束为[undefined, XXXX] ,其中XXXX总是最后请求的Content-Length的大小

我很困惑,虽然这似乎是一个时间/范围问题。 我在这里遇到种族情况吗?

问题是callback函数捕获的单个variablesiajaxSizeRequest对于callback函数的所有实例都是相同的variables。 我认为,如果你调用一个函数并将索引variables传递给它,并且同时将请求variables的范围局限于函数本身,则使用done处理程序的响应参数,最终应该由callback捕获的独立variables。 然后它应该正确引用每个数组元素和每个响应variables。

 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')]); }); } 

看起来像你i正确封闭

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

只需包装你的successcallback函数,如下所示,更改引用ajaxSizeRequest

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

你可以像我这样的范围:

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

你有一个单一的i所有的callback共享的variables。
由于AJAX是asynchronous的,所有的callback在你的循环完成后运行,并且它们都得到相同的i

为了解决这个问题,你需要把AJAX调用转换成一个独立的函数,把i作为参数。
因此,每个callback将获得一个单独的i参数。

如果任何人仍然遇到这个问题,并且自从这篇文章已经有5年的历史,那么下面是一个更“现代”的答案:只要在原始文章的for循环中使用let而不是var

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