Reputation: 21512
Is it possible to access the XMLHttpRequest
object from the success callback of the $.ajax()
function? Specifically I need access to XMLHttpRequest.responseBody
in IE. Per the documentation the returned jqXHR
object does not expose the .responseBody
property.
This seems to be a minor oversite that has a huge impact when dealing with binary data. If the .responseBody
property or the underlying XMLHttpRequest
object is not accessible I'll have to skip jQuery for ajax and code it in, shudder, pure javascript.
I am infact looking for the responceBody
variable, not the responceText
variable that is readily accessible from within $.ajax()
Upvotes: 12
Views: 14406
Reputation: 4010
Provide the xhr settings field to create the XMLHttpRequest, and retain a reference to the object. A quick way to do this is by adding it to the settings object (which is accessible via this
in the callbacks).
$.ajax({
url: "/whatever",
xhr: function(){
return this._xhr = new XMLHttpRequest();
},
success: function(){
console.log("Original XHR:", this._xhr);
}
});
Upvotes: 3
Reputation: 1276
I know this is an old question, but I just solved it.
What do we know about the situation? We know that jQuery no longer passes around the original XmlHttpRequest object, nor any references to it. We know that instead if passes around a "superset" that has most of the attributes. AND, we know that jQuery still uses an XmlHttpRequest to do the AJAX call.
So, if the browser still gets a callback and is passed the actual XmlHttpRequest, can we programatically access it? Using arguments.callee.caller
, Yes. We. Can.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee
By the time your hook fires (success
, fail
, whatever), you have just a few guarantees: You are in the callback callstack, the first function (the callback) has the XHR, and it has no caller
.
So, loop through the callstack (arguments.callee.caller.arguments.callee.caller...
) until the caller
is null
, then look at the arguments
! The first argument will be the callback Event object, and that event will have the XHR object created by the browser in the srcElement
attribute.
$.ajax({
url: 'https://httpbin.org/redirect-to?url=http%3A%2F%2Fexample.com%2F',
type: 'get',
success: function(data, textStatus, jqXHR) {
var caller = arguments.callee.caller;
while(caller.arguments.callee.caller != null) {
caller = caller.arguments.callee.caller;
}
console.log(caller.arguments[0]);
console.log(caller.arguments[0].srcElement.responseURL);
}
});
Upvotes: 1
Reputation: 2244
The xhr function for the ajax request can be overriden.
$.ajax({
...
xhr: function(){
var xhr = jQuery.ajaxSettings.xhr();
// do stuff with xhr;
return xhr;
}
});
Or to elaborate on Manuel Bitto's answer, the xhr instance can be accessed from beforeSend callback:
$.ajax({
beforeSend: function(jqXHR, settings){
var xhr = jQuery.ajaxSettings.xhr();
settings.xhr = xhr
// Do stuff with the xhr instance for this request
xhr.onprogress = function(){
}
console.log(xhr);
}
});
Upvotes: 7
Reputation: 5253
You can use beforeSend callback too:
$.ajax({
beforeSend: function(jqXHR, settings){
// Here you are the XHR object
console.log(settings.xhr());
}
});
Upvotes: 9
Reputation: 9138
I, too, was looking to get at the underlying XMLHttpRequest object in order to get at the 'onprogress' and 'upload' properties (found in more recent browsers that use XMLHttpRequest2) so that I could do native upload progress handling instead of using hacks. After digging through the jQuery source I found that you CAN get at it via jQuery.ajaxSettings.xhr()
. It's a function that returns a raw XMLHttpRequest.
See here: https://github.com/jquery/jquery/blob/master/src/ajax/xhr.js
Hope that helps.
Upvotes: 2