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

后端 未结 14 2287
暗喜
暗喜 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 05:51

    Keep in mind that if you're doing a cross-domain Ajax call (by using JSONP) - you can't do it synchronously, the async flag will be ignored by jQuery.

    $.ajax({
        url: "testserver.php",
        dataType: 'jsonp', // jsonp
        async: false //IGNORED!!
    });
    

    For JSONP-calls you could use:

    1. Ajax-call to your own domain - and do the cross-domain call server-side
    2. Change your code to work asynchronously
    3. Use a "function sequencer" library like Frame.js (this answer)
    4. Block the UI instead of blocking the execution (this answer) (my favourite way)
    0 讨论(0)
  • 2020-11-21 05:54

    Note: You shouldn't use async: false due to this warning messages:

    Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), synchronous requests on the main thread have been deprecated due to the negative effects to the user experience.

    Chrome even warns about this in the console:

    Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

    This could break your page if you are doing something like this since it could stop working any day.

    If you want to do it a way that still feels like if it's synchronous but still don't block then you should use async/await and probably also some ajax that is based on promises like the new Fetch API

    async function foo() {
      var res = await fetch(url)
      console.log(res.ok)
      var json = await res.json()
      console.log(json)
    }
    

    Edit chrome is working on Disallowing sync XHR in page dismissal when the page is being navigated away or closed by the user. This involves beforeunload, unload, pagehide and visibilitychange.

    if this is your use case then you might want to have a look at navigator.sendBeacon instead

    It is also possible for the page to disable sync req with either http headers or iframe's allow attribute

    0 讨论(0)
  • 2020-11-21 05:56

    You can put the jQuery's Ajax setup in synchronous mode by calling

    jQuery.ajaxSetup({async:false});
    

    And then perform your Ajax calls using jQuery.get( ... );

    Then just turning it on again once

    jQuery.ajaxSetup({async:true});
    

    I guess it works out the same thing as suggested by @Adam, but it might be helpful to someone that does want to reconfigure their jQuery.get() or jQuery.post() to the more elaborate jQuery.ajax() syntax.

    0 讨论(0)
  • 2020-11-21 05:59

    Excellent solution! I noticed when I tried to implement it that if I returned a value in the success clause, it came back as undefined. I had to store it in a variable and return that variable. This is the method I came up with:

    function getWhatever() {
      // strUrl is whatever URL you need to call
      var strUrl = "", strReturn = "";
    
      jQuery.ajax({
        url: strUrl,
        success: function(html) {
          strReturn = html;
        },
        async:false
      });
    
      return strReturn;
    }
    
    0 讨论(0)
  • 2020-11-21 05:59

    All of these answers miss the point that doing an Ajax call with async:false will cause the browser to hang until the Ajax request completes. Using a flow control library will solve this problem without hanging up the browser. Here is an example with Frame.js:

    beforecreate: function(node,targetNode,type,to) {
    
        Frame(function(next)){
    
            jQuery.get('http://example.com/catalog/create/', next);
        });
    
        Frame(function(next, response)){
    
            alert(response);
            next();
        });
    
        Frame.init();
    }
    
    0 讨论(0)
  • 2020-11-21 05:59
    function getURL(url){
        return $.ajax({
            type: "GET",
            url: url,
            cache: false,
            async: false
        }).responseText;
    }
    
    
    //example use
    var msg=getURL("message.php");
    alert(msg);
    
    0 讨论(0)
提交回复
热议问题