7

i am making simple autosuggestion (autocompleter) plugin with jQuery. Unfortunately i have to use jsonp. It is ok and it works, but when i am aborting request it will throw error.

Uncaught TypeError: Property 'jQuery171036404498340561986_1330693563756' of object [object Window] is not a function

There is code

if(xhr) {xhr.abort()};
xhr = $.ajax({
    url: "someurl/getmedata",
    type: 'get',
    dataType: 'jsonp',
    data: {q: "query"},
    success: function(results) {},
    error: function() {}
})

Classic way with json, xml or other request works fine.

Anny suggestion?

gion_13
  • 41,171
  • 10
  • 96
  • 108
Schovi
  • 1,960
  • 5
  • 19
  • 33
  • This question is a duplicate of the earlier [Abort JSONP ajax request with jQuery](http://stackoverflow.com/questions/6472509/abort-jsonp-ajax-request-with-jquery), though that question was never properly answered and this one was. – Trevor Burnham Apr 03 '12 at 18:56

3 Answers3

14

JSONP does not use XMLHTTPRequest but actually creates a <script> tag within the document to be able to make the cross-domain requests.

You simply cannot abort JSONP requests.

It is stated in the $.ajax() documentation:

Some types of Ajax requests, such as JSONP and cross-domain GET requests, do not use XHR; in those cases the XMLHttpRequest and textStatus parameters passed to the callback are undefined.

As for jQuery 1.5+, previously was returning the XHR object from $.ajax(), now it returns a superset jqXHR object which encapsulates the XHR object.

When the transport mechanism is something other than XMLHttpRequest (for example, a script tag for a JSONP request) the jqXHR object simulates native XHR functionality where possible.

So it returns an object but some functionnalities are actually not available, like .abort().


The plugin jQuery-JSONP seems to offer the possibility to manually abort JSONP requests. I haven't used it myself but it's worth giving it a try.

Timo Tijhof
  • 10,032
  • 6
  • 34
  • 48
Didier Ghys
  • 30,396
  • 9
  • 75
  • 81
  • Ok get it. Is there any other way how to handle missing function in global context? – Schovi Mar 02 '12 at 19:35
  • 1
    I've added a link to the plugin [jquery-jsonp](http://code.google.com/p/jquery-jsonp/) which seems to offer the possiblity to abort jsonp requests. – Didier Ghys Mar 02 '12 at 20:35
  • Is it ok to use dynamic callback name? like `callback = random()` `$.jsonp({url: "my_url?callback=" +callback, callback: callback})` – Schovi Mar 09 '12 at 09:37
  • Honnestly I don't much about this plugin, I just head about it. According to [documentation](http://code.google.com/p/jquery-jsonp/wiki/APIDocumentation) it seems possible yes. – Didier Ghys Mar 09 '12 at 10:27
  • For me, the problem was I was adding a timeout value. – Moishe Lipsker Oct 29 '15 at 22:25
4

jQuery uses a <script> tag to implement JSONP. You cannot abort the loading of script tags.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
0

First of all, use some sequencing logic. This will assure your last request prevails over the old ones. Here you have an example.

Also, you can take advantage of these $.ajax settings:

timeout: set a time limit per request and prevent requests fail silently.

beforeSend: validate some conditions before making the call. Complements sequencing helper.

As of jQuery 1.5, the beforeSend option will be called regardless of the type of request.

Example:

function updateResults() {

  // Init counter & record current request
  if (!window.reqSeq)  window.reqSeq = 0;
  window.reqSeq +=1;
  var thisRequest = window.reqSeq;

  $.ajax({
    url: [..],
    crossDomain: true, 
    contentType: "application/json",
    dataType: 'jsonp',
    timeout: 5000, // give 5 seconds of margin
    data: { [..] },
    beforeSend: function() {
      if(thisRequest < window.reqSeq) {
        return false;
      }
    },
    success: function(data, textStatus, jqXHR) {
      if(thisRequest < window.reqSeq) {
        return;
      }
      else print(data);
    },
    error: function(jqXHR, textStatus, errorThrown) {
      // it'll be called on timeout (error) and beforeSend (abort)
      print(textStatus);
    }
  });

}
Oriol
  • 11,660
  • 5
  • 35
  • 37