Ilja Bulatov Ilja Bulatov - 4 months ago 19
Ajax Question

Why async ajax request doesn't work?

I'm new in javascript. I'm using this script to auth in my api:

function try_login() {
$.ajax({
type: "POST",
url: "http://some.api/auth",
dataType: 'json',
async: false,
data: {
username: document.getElementById('username').value,
password: document.getElementById('password').value
},
success: function (data)
{
// alert(data.jwt_token);
window.sessionStorage.setItem('token', data.jwt_token);
// alert(window.location);
window.location.replace("/index.html");
// alert(window.location);
return false;
}
// success: successLogin,
});
}


And this is my html (also I'm using bootstrap):

<form class="form-signin" role="form">
<h2 class="form-signin-heading">Please sign in</h2>
<input id="username" type="username" class="form-control" placeholder="Username" required="" autofocus="">
<input id="password" type="password" class="form-control" placeholder="Password" required="">
<button class="btn btn-lg btn-primary btn-block" type="submit" id="login_btn" onclick="try_login()">Sign in</button>
</form>


I have two troubles.
Firstly, why if I'll change async on true or remove it (because default is async true in ajax), it will not been send a post request to api, it will only refresh a page.

Secondly, when I use an async false post request, it makes normaly request to api and receives normaly response. Saving token in sessionStorage works perfectly, but window.location.replace doesn't redirect on next page. I also trying many kinds of this, such as:

window.location = "/index.html"

window.location.href = "/index.html"


and also trying set non relative path "www.mysite.com/index.html".

The Chrome warning says that synchronous request deprecated, but my first trouble as you can see I don't know how to use async request.
Also, it seems like a magic, but if I uncomment all my allerts in success function, firefox will redirect me to "index.html".

Please, help me!

Answer

Firstly, why if I'll change async on true or remove it (because default is async true in ajax), it will not been send a post request to api, it will only refresh a page.

Because you're submitting a form, which involves tearing down the page and cancels any in-progress ajax requests.

Secondly, when I use an async false post request, it makes normaly request to api and receives normaly response. Saving token in sessionStorage works perfectly, but window.location.replace doesn't redirect on next page.

Because you're submitting a form. The return false in your success callback has no effect whatsoever on the submit event of the form. If you want to prevent the form submission from within the success handler, hook the try_login up with jQuery (not onclick attributes), accept the event object, and use preventDefault() on it.


It looks to me like you never really want to submit the form, and instead just want to use it to trigger ajax. If that's the case, there's no need to make your ajax synchronous (and good reasons not to):

function try_login() {
    $.ajax({
        type: "POST",
        url: "http://some.api/auth",
        dataType: 'json',
        data: {
            username: document.getElementById('username').value,
            password: document.getElementById('password').value
        },
        success: function(data) {
            window.sessionStorage.setItem('token', data.jwt_token);
            window.location.replace("/index.html");
        }
    });
    return false;
}

Remove the onclick and hook it up like this:

$("any-css-selector-for-the-form").on("submit", try_login);

You might want to show something to indicate the request is in progress.

Comments