简体   繁体   中英

How can I replace a sync ajax call with credentials to keep my app's state stable

I know that Firefox and jQuery don't allow sync requests with credentials. My problem is that I need to know if the user is logged in or not (by checking his session on the server by hitting an /echo endpoint).

Otherwise my Backbone application enters a bad state because when I navigate to a backbone route like #newActivity there is this logic in my controller:

         if (Session.status!=Session.LOGGED_IN) {
            Backbone.history.navigate('login', true);
            return;
        }

Session is a singleton object. In there if I hit async the /echo endpoint, until the time success is called my controller already thinks that we are not logged in. Outcome: when the user refreshed the page he is always redirected in the login prompt.

If I make the request sync everything works ok with Chrome.

The request is:

 $.ajax({
            url: Config.serverUrl + "/rest/auth/echo",
            type: 'GET',
            dataType: "json",
            async:false,
            xhrFields: {
                withCredentials: true
            },
/*            beforeSend: function(xhr) {
                xhr.withCredentials = true;
            },*/
            crossDomain: true,
            success: function (data) {
                self.bootstrap(data)
                self.globalCh.vent.trigger('loggedIn',data.username);
            }
        });

I kind of understand why they want to phase out sync queries, but sometimes they are necessary for not having an unstable application state.

Any workarounds or ideas about a better implementation?

you need to use promises and/or deferred objects. http://api.jquery.com/category/deferred-object/

jQuery's AJAX call returns a promise. That means you can fire a callback whereever you want to when the ajax call is finished.

add a return to your ajax request.

function getLoginInformation() {
    return $.ajax({
        // your ajax call to check if the user is logged in or not
    });
}

and then on page load, you fire the stuff that needs the login information AFTER you have it. Like this:

getLoginInformation().then(function(data) {
    // load the app and everything else that needs credentials
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM