0

I have func in Go (I have removed all error handling to make this short)

func PostLoginAjax(w http.ResponseWriter, r *http.Request) {
    if r.Method == "POST" {
        userEmail := r.FormValue("Email")
        userPassword := r.FormValue("Password")
        db := r.Context().Value( "db").(*sqlx.DB)
        sessionStore := r.Context().Value( "sessionStore").(sessions.Store)
        u := models.NewUser(db)
        user, err := u.GetUserByEmailAndPassword(nil, userEmail, userPassword)
        session, _ := sessionStore.Get(r, "superadmin-session")
        session.Values["user"] = user
        err = session.Save(r, w)
        log.Info("All Success, redirecting to: ", "/")
        w.Header().Set("Location", "/")
        w.WriteHeader(http.StatusFound)
    }
}

Below is the snippet from template which is being used

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
        $(document).ready(function(){
            $("#login-submit").on('click', function(){
                $.ajaxSetup({async: true, cache: false});
                $.ajax({
                    url: '/login', // url where to submit the request
                    type : "POST", // type of action POST || GET
                    data : $("#form-login").serialize(), // post data || get data
                    success: function (response, status, xhr) {
                        console.log("success");
                        console.log(status);
                        console.log(xhr);
                        console.log(response);
                        },
                    error: function (errMsg) {
                        console.log("error");
                        console.log(errMsg);
                        $("#formErrorMessage").html(errMsg);
                    },
                    complete: function(resp) {
                        console.log("complete");
                        console.log(resp);
                    }
                })
            });
        });
</script>

If I just the code shown above and when I click "Login" button and I go and check in console logs I see something like show below

console log screenshot

Things which I do not understand is why the page is not redirected as in the Network tab of devtools I see the status is 302 and in console log I see status 200. Why this difference. When I just simply refresh the page, it perfectly works fine and takes me to the logged in page and from there I have to logout to test again.

How can I actually make this work, like submit form using ajax and then redirect if email and password are verified.

If I remove the below line from the func, the response is handled by the error part of ajax and same thing happens, I get the complete HTML in response text in console log and the #formErrorMessage actually shows the HTML (parsed) with all images and text. When I just simply refresh the page, it takes to the logged in page and from there I have to logout.

w.Header().Set("Location", "/")

I would like to know, is this the normal behavior or I am missing something. I initially implemented this using a normal http.Redirect without AJAX which was working fine and now I am trying to get this to work using AJAX and its just not working.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Mudasir Mirza
  • 171
  • 3
  • 13

1 Answers1

0

When you set the Location header on your server, it's only set for this one AJAX request. It is correctly being redirected to /, which is why you can see that html in the browser console.

Since this request is separate from your "normal" web browser traffic, you have to handle the redirect in your JavaScript code yourself, e.g. put this in the success function:

document.location = document.location.protocol + "//" + document.location.host

You could also implement an API endpoint for logging in that returns whether the login was successful, and then call this endpoint in your AJAX request. On success, you client code has to handle the redirect.

xarantolus
  • 1,961
  • 1
  • 11
  • 19