How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?

后端 未结 14 2288
暗喜
暗喜 2020-11-21 05:07

I have a JavaScript widget which provides standard extension points. One of them is the beforecreate function. It should return false to prevent an

相关标签:
14条回答
  • 2020-11-21 06:00

    I used the answer given by Carcione and modified it to use JSON.

     function getUrlJsonSync(url){
    
        var jqxhr = $.ajax({
            type: "GET",
            url: url,
            dataType: 'json',
            cache: false,
            async: false
        });
    
        // 'async' has to be 'false' for this to work
        var response = {valid: jqxhr.statusText,  data: jqxhr.responseJSON};
    
        return response;
    }    
    
    function testGetUrlJsonSync()
    {
        var reply = getUrlJsonSync("myurl");
    
        if (reply.valid == 'OK')
        {
            console.dir(reply.data);
        }
        else
        {
            alert('not valid');
        }    
    }
    

    I added the dataType of 'JSON' and changed the .responseText to responseJSON.

    I also retrieved the status using the statusText property of the returned object. Note, that this is the status of the Ajax response, not whether the JSON is valid.

    The back-end has to return the response in correct (well-formed) JSON, otherwise the returned object will be undefined.

    There are two aspects to consider when answering the original question. One is telling Ajax to perform synchronously (by setting async: false) and the other is returning the response via the calling function's return statement, rather than into a callback function.

    I also tried it with POST and it worked.

    I changed the GET to POST and added data: postdata

    function postUrlJsonSync(url, postdata){
    
        var jqxhr = $.ajax({
            type: "POST",
            url: url,
            data: postdata,
            dataType: 'json',
            cache: false,
            async: false
        });
    
        // 'async' has to be 'false' for this to work
        var response = {valid: jqxhr.statusText,  data: jqxhr.responseJSON};
    
        return response;
    }
    

    Note that the above code only works in the case where async is false. If you were to set async: true the returned object jqxhr would not be valid at the time the AJAX call returns, only later when the asynchronous call has finished, but that is much too late to set the response variable.

    0 讨论(0)
  • 2020-11-21 06:03

    Because XMLHttpReponse synchronous operation is deprecated I came up with the following solution that wraps XMLHttpRequest. This allows ordered AJAX queries while still being asycnronous in nature, which is very useful for single use CSRF tokens.

    It is also transparent so libraries such as jQuery will operate seamlessly.

    /* wrap XMLHttpRequest for synchronous operation */
    var XHRQueue = [];
    var _XMLHttpRequest = XMLHttpRequest;
    XMLHttpRequest = function()
    {
      var xhr   = new _XMLHttpRequest();
      var _send = xhr.send;
    
      xhr.send = function()
      {
        /* queue the request, and if it's the first, process it */
        XHRQueue.push([this, arguments]);
        if (XHRQueue.length == 1)
          this.processQueue();
      };
    
      xhr.processQueue = function()
      {
        var call = XHRQueue[0];
        var xhr  = call[0];
        var args = call[1];
    
        /* you could also set a CSRF token header here */
    
        /* send the request */
        _send.apply(xhr, args);
      };
    
      xhr.addEventListener('load', function(e)
      {
        /* you could also retrieve a CSRF token header here */
    
        /* remove the completed request and if there is more, trigger the next */
        XHRQueue.shift();
        if (XHRQueue.length)
          this.processQueue();
      });
    
      return xhr;
    };
    
    0 讨论(0)
提交回复
热议问题