6

I have been trying to setup custom ajaxTransports for jQuery to short-circuit some workflows in certain scenarios for our product. However, I have had zero success in getting these transports to be honored (whereas I have many working custom ajaxPrefilters).

Tested with multiple versions of jQuery:

  • 1.5.2
  • 1.6.4
  • 1.7.2
  • 1.8.0

Tested with multiple browsers:

  • Firefox 15
  • Chrome 21
  • iOS 5 webviews

...

None of them worked.

JsFiddle test case: http://jsfiddle.net/PVYut/

...

If I add a dataType to narrow it down, then it works fine.

JsFiddle test case: http://jsfiddle.net/PVYut/1/

...

Am I just doing something all wrong? I'd be happy to be told so, so long as I can get this working! -_-

James M. Greene
  • 1,251
  • 1
  • 16
  • 23

1 Answers1

3
$.ajaxTransport("+*", function(options, originalOptions, jqXHR, headers, completeCallback   ) {
    console.log("Executing ajaxTransport");
    return {
        send: function( headers, completeCallback ) {
            completeCallback(404, "error", {});
        },
        abort: function() {
          /* abort code */
        }
    }
});

$.ajax("?jqTrans=" + (+(new Date())))
    .done(function() {
        console.log("ERROR: Should not have been successful!");
    })
    .fail(function() {
        console.log("SUCCESS: Should have failed.");  
    });

Here is jsFiddle

James M. Greene
  • 1,251
  • 1
  • 16
  • 23
Viktor S.
  • 12,736
  • 1
  • 27
  • 52
  • 1
    Nice, thanks! Another case of poor documentation for jQuery. =( – James M. Greene Sep 18 '12 at 18:47
  • 2
    Usually, transports are used as fallbacks. You should never rely on transport ordering like this (hence why it is not documented). Create a prefilter, redirect to another dataType and capture this dataType with your custom transport is the way to go. Sorry to be late to the party. – Julian Aubourg Sep 18 '12 at 20:38
  • @JulianAubourg I considered doing exactly what you described but the thought of obscuring the real `dataType` put me off. At best, you could store the real `dataType` value in a new property on the `options`/`settings` object for the request in the prefilter and then restore it to the `dataType` property in the transport. Doable but it makes it feel hackier. – James M. Greene Sep 18 '12 at 21:34
  • 2
    In your prefilter: "return 'myDataType';" in you transport: "options.dataTypes.shift();" -> done! and you even kept the dataType chain. If you think of a mock ajax for instance, it makes a lot of sense: $.ajaxPrefilter(function( options ) { if ( options.mock ) { return "mock"; }); $.ajaxTransport( "mock", function( options ) { options.dataTypes.shift(); /* Now I have the actual dataType chain to do my mocking */ }); I think it's actually pretty elegant. – Julian Aubourg Sep 18 '12 at 21:45
  • @JulianAubourg Once again, sounds like a result of poor documentation: the `dataTypes` property of the `options`/`settings` object does not appear to be mentioned anywhere either. I would agree that your modified suggestion is likely more preferable. In my mind, I was picturing the need to do it more like this ugliness: `$.ajaxPrefilter(function(o) { if (o.mock) { o.origDataType = o.dataType; o.dataType = "mock"; }});` `$.ajaxTransport("mock", function(o) { o.dataType = o.origDataType; delete o.origDataType; /* pertinent real code */ });` – James M. Greene Sep 19 '12 at 18:36
  • 2
    It's quite difficult to talk about internal options (like dataTypes) in the API site. I hope to find some time to properly document all of this separately. – Julian Aubourg Sep 19 '12 at 19:08