Justin808
Justin808

Reputation: 21512

jQuery $.ajax() functionality - Accessing the XMLHttpRequest object

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.

Update

I am infact looking for the responceBody variable, not the responceText variable that is readily accessible from within $.ajax()

Upvotes: 12

Views: 14406

Answers (5)

Glenn Lane
Glenn Lane

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

Nate
Nate

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

Macario
Macario

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

Manuel Bitto
Manuel Bitto

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

Aquarelle
Aquarelle

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

Related Questions