通过Javascript/jQuery的Ajax头部请求
我似乎在发出通过Javascript/jQuery的Ajax头部请求,javascript,jquery,ajax,http-headers,Javascript,Jquery,Ajax,Http Headers,我似乎在发出HEAD请求以及保护数组中数据的完整性方面遇到了一些问题 鉴于此片段: var imageTemp = Array(); $('*') .each(function(index){ if($(this).css('background-image') != 'none'){ imageTemp.push($(this).css('background-image').slice(5, -2)); } });
HEAD
请求以及保护数组中数据的完整性方面遇到了一些问题
鉴于此片段:
var imageTemp = Array();
$('*')
.each(function(index){
if($(this).css('background-image') != 'none'){
imageTemp.push($(this).css('background-image').slice(5, -2));
}
});
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')]);
}
});
}
我捕获给定页面上所有背景图像的URL。现在,通过HEAD
请求Content Length
获取每个图像的大小,我使用以下代码片段:
var imageTemp = Array();
$('*')
.each(function(index){
if($(this).css('background-image') != 'none'){
imageTemp.push($(this).css('background-image').slice(5, -2));
}
});
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')]);
}
});
}
var-imageData=Array();
对于(变量i=0;i
但是,当我通过console.log
转储imageData
时,我发现每个元素(应该是一个包含URL和内容长度的数组)最终都是[未定义,XXXX]
,其中XXXX
始终是上次请求的内容长度的大小
我被难住了,尽管这似乎是一个时间/范围问题。我这里有某种竞争条件吗?您有一个由所有回调共享的
I
变量。因为AJAX是异步的,所以所有回调都在循环完成后运行,它们都得到相同的
i
要解决这个问题,您需要将AJAX调用移动到一个单独的函数中,该函数将i
作为参数。因此,每个回调都将获得一个单独的
i
参数。看起来您的i
没有正确关闭
此外,不能使用ajaxSizeRequest
,因为它也只指向一个请求(可能是最后一个,因为循环执行得非常快)
只需将success
回调函数包装如下,将引用更改为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
和ajaxSizeRequest
对于回调函数的所有实例都是相同的变量。我认为,如果调用一个函数并将索引变量传递给它,同时使用done处理程序的response参数将请求变量局部作用于函数本身,那么回调函数应该捕获独立变量。然后它应该正确地引用每个数组元素和每个响应变量
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')]);
});
}
var-imageData=Array();
对于(变量i=0;i
如果有人对此仍有疑问,并且由于这篇文章已经有5年了,这里有一个更“现代”的答案:只需使用let
而不是原始文章的for
循环中的var
信息:
并且:您可以使用
success
回调的第二个参数,而不是ajaxSizeRequest
变量;这很有魅力。我使updateImageData
匿名以避免污染我的脚本。避免使用success
,防止代码混乱!,使用.done(函数(文本、状态、xhr){……};
。@EladKarako-相当旧的答案,我已经更新以反映当前的最佳实践。感谢更新,b.t.w,答案是永恒的;)(……好吧……至少谷歌会在前5个结果中建议它)。