Ajax HEAD request via Javascript/jQuery
Solution 1
The problem is that the single variables i
and ajaxSizeRequest
being 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 itself use 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.
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')]);
});
}
Solution 2
looks like your i
isnt properly closed-in
in addition, you can't use ajaxSizeRequest
because it too is pointing to just one request (probably the last, because the loop will execute very fast)
just wrap your success
callback function as follows, changing the reference to ajaxSizeRequest
:
success: (function(i){
return function(data,status,xhr){
imageData.push([imageTemp[i], xhr.getResponseHeader('Content-Length')]);
};
})(i)
Solution 3
You can scope I like so:
success: function(i){
return function(message){
imageData.push([imageTemp[i], ajaxSizeRequest.getResponseHeader('Content-Length')]);
}
}(i)
Comments
-
Dan Lugg almost 4 years
I seem to be having some issues with making
HEAD
requests, and preserving the integrity of data in an array.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
HEAD
requests forContent-Length
, I use this snippet: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
imageData
viaconsole.log
, I each element (which should be an array containing the URL and the content-length) ends up as[undefined, XXXX]
whereXXXX
is always the size of the last requestedContent-Length
I'm stumped, though it appears to be a timing/scoping issue. Do I have a sort of race-condition occuring here?
-
Dan Lugg over 13 yearsThanks alot tvanfosson; That works like a charm. I made
updateImageData
anonymous to avoid pollution of my script. -
Admin about 9 yearsavoid using
success
, prevent code-clutter!, use.done(function(text, status, xhr){ ...... };
instead. -
tvanfosson about 9 years@EladKarako - pretty old answer, I've updated to reflect current best practice.
-
Admin about 9 yearsthanks for the update, b.t.w, answer(s) are timeless ;) (.....well.. at-least as long Google will suggest it in the first 5 results).