Stop Duplicate Ajax Submisions?
Asked Answered
C

4

10

I am wondering what is the best way to stop duplciate submissions when using jquery and ajax?

I come up with 2 possible ways but not sure if these are the only 2.

  1. On Ajax start disable all buttons till request is done. 2 problems I see with this though is I use jquery model dialog so I don't know how easy it would be to disable those button as I not sure if they have id's. Second I if the the request hangs the user has really no way to try again since all the buttons are disabled.

  2. I am looking into something called AjaxQueue at this time I have no clue if it is what I need or how it works since the site where the plugin is apparently down for maintenance.

http://docs.jquery.com/AjaxQueue

Edit

I think this is a spin off of what I was looking at.

http://www.protofunc.com/scripts/jquery/ajaxManager/

The only problem I see with this ajaxManager is that I think I have to change all my $.post, $.get and $.ajax ones to their type.

But what happens if I need a special parameter from $.ajax? Or that fact I like using .post and .get.

Edit 2

I think it can take in all $.ajax options. I am still looking into it. However what I am unsure about now is can I use the same constructor for all requests that will use the same options.

First you have to construct/configure a new Ajaxmanager
//create an ajaxmanager named someAjaxProfileName
var someManagedAjax = $.manageAjax.create('someAjaxProfileName', {
    queue: true, 
    cacheResponse: true
});

Or do I have to make the above every single time?

Cruise answered 2/6, 2010 at 16:31 Comment(0)
B
21

How about setting a flag when the user clicks the button? You will only clear the flag when the AJAX request completes successfully (in complete, which is called after the success and error callbacks), and you will only send an AJAX request if the flag is not set.

Related to AJAX queuing there is a plugin called jQuery Message Queuing that is very good. I've used it myself.

var requestSent = false;

jQuery("#buttonID").click(function() {   
   if(!requestSent) {
      requestSent = true;

      jQuery.ajax({
         url: "http://example.com",
         ....,
         timeout: timeoutValue,
         complete: function() {
             ...
             requestSent = false;
         },
      });
   }
});

You can set a timeout value for long-running requests (value is in milliseconds) if you think your request has a possibility of hanging. If an timeout occurs, the error callback is called, after which the complete callback gets called.

Belleslettres answered 2/6, 2010 at 17:0 Comment(0)
T
9

You could store an active request in a variable, then clear it when there's a response.

var request;  // Stores the XMLHTTPRequest object

$('#myButton').click(function() {
    if(!request) {  // Only send the AJAX request if there's no current request 

        request = $.ajax({  // Assign the XMLHTTPRequest object to the variable
            url:...,
            ...,
            complete: function() { request = null } // Clear variable after response
        });

    }
});

EDIT:

One nice thing about this, is that you could cancel long running requests using abort().

var request;  // Stores the XMLHTTPRequest object
var timeout;  // Stores timeout reference for long running requests

$('#myButton').click(function() {
    if(!request) {  // Only send the AJAX request if there's no current request 

        request = $.ajax({  // Assign the XMLHTTPRequest object to the variable
            url:...,
            ...,
            complete: function() { timeout = request = null } // Clear variables after response
        });

        timeout = setTimeout( function() {
                        if(request) request.abort();  // abort request
                  }, 10000 );                         //   after 10 seconds

    }
});
Tempestuous answered 2/6, 2010 at 16:57 Comment(2)
Wouldn't using the timeout property be easier? Or does it not work the way I think it does? :)Belleslettres
@Vivin - Good point. Unless there's some other logic that you want to use in the setTimeout() to decide whether or not to abort, you could use the timeout property. The request variable is a flag like in your answer, but with the added benefit of providing abort() functionality if needed.Tempestuous
L
0
$.xhrPool = {};
$.xhrPool['hash'] = []
$.ajaxSetup({
    beforeSend: function(jqXHR,settings) {
        var hash = settings.url+settings.data
        if ( $.xhrPool['hash'].indexOf(hash) === -1 ){
            jqXHR.url   = settings.url;
            jqXHR.data  = settings.data;
            $.xhrPool['hash'].push(hash);
        }else{
            console.log('Duplicate request cancelled!');
            jqXHR.abort();
        }
    },
    complete: function(jqXHR,settings) {
        var hash = jqXHR.url+jqXHR.data 
            if (index > -1) {
                $.xhrPool['hash'].splice(index, 1);
            }
        }
    }); 
Langston answered 7/6, 2017 at 13:47 Comment(0)
I
0

heres a "return method"

it will not execute the ajax code again until it is done processing

var firstenter = true;

jQuery("#buttonID").click(function() { 
  if (!firstenter){
     return;
  }
  firstenter = false;
  jQuery.ajax({
     url: "http://example.com",
     ....,
     timeout: timeoutValue,
     complete: function() {
         ...
         firstenter = true;
     },
  });
});
Intelligible answered 5/3 at 9:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.