0

I currently have a POST request which will in any case set location in the response header to go to the exact same page again.

1) I click sign in. As you can see, the location is set to / which is the same page in this case. Request is handled by the server then a redirect via the location field is set in the response header.

enter image description here

2) Down below is the get request for the same address as the sign in page (not to be confused with /auth/local which only receives a post with login credentials). / is a different page when logged in due to routing in node.

enter image description here

3) As you can see below, the preview shows the html of the response to the get request which was initiated by the response of the post request. It's not the same as what the actual browser is showing which is the initial login page. It doesn't seem to update the browser?

enter image description here

Timeline:

enter image description here

I'm running Angular also:

main.js

angular.module('myApp', [])
    .controller('publicHomeCtrl', ['$scope', '$http', function ($scope, $http) {
        $scope.submit = function (event) {
            var data = {
                email: $scope.email,
                password: $scope.password
            };
            $http.post('/auth/local', data).success(function () {
                console.log('success');
            });
            event.preventDefault();
        };
        $scope.submit2 = function () {
            var data = {
                email: $scope.email,
                password: $scope.password
            };
            $http.post('/auth/local', data).success(function () {
                console.log('success');
            });
        };
}]);

signin html

<div class="container" data-ng-controller="publicHomeCtrl">
    <form method="post" role="form" ng-submit="submit($event)">
        <input type="email" data-ng-model="email" placeholder="your@email.here" class="form-control">
        <input type="password" data-ng-model="password" placeholder="password" class="form-control">
        <button type="submit" class="btn btn-success">sign in 1</button>
    </form>
    <button ng-click="submit2()">sign in 2</button>
</div>

I'm suspecting because my http.post on the client side has a callback it cancels out the redirect in the response header from actually updating the view?

basickarl
  • 37,187
  • 64
  • 214
  • 335
  • Is this a form post in the browser page? If so, are you doing the submission via Javascript? If so, are you preventing the default form submission? If you aren't preventing the default, then your ajax submits the form, then the browser submits the form and the ajax response is lost. I don't know if this applies to you exactly (it depends upon client-side code that we can't see), but this is a very common mistake (not preventing the default form submission which just causes a page reload). – jfriend00 Sep 23 '15 at 00:07
  • It does indeed look like you are probably getting a default form submission which is reloading the page before your Ajax response gets processed. See my answer below for a couple solutions. – jfriend00 Sep 23 '15 at 00:14
  • @jfriend00 Updated the code with one way to get rid of preventDefault, doesn't seem to work :/ – basickarl Sep 23 '15 at 00:23
  • The way the code is now, it would need to be `event$.preventDefault();`, not `event.preventDefault()` if the `event$` argument is the right event. Are you entirely sure you're passing the event object the proper way for angular? I see something different here: http://stackoverflow.com/questions/21101492/automatically-pass-event-with-ng-click – jfriend00 Sep 23 '15 at 00:34
  • @jfriend00 Still the same :( – basickarl Sep 23 '15 at 00:36
  • Well, I'm pretty sure this is the issue. You can verify by just watching the network trace in the browser and you should see a page reload right after you see your ajax call get sent. You will have to figure out how to properly prevent the default form action in angular. – jfriend00 Sep 23 '15 at 00:38
  • You can see once and for all if this is the issue by looking at the browser network tab to see if the form reload is happening. If that's not it, then you must be doing something wrong with the location header. Since I can't debug it here, I'm just offering you the best guesses I have. – jfriend00 Sep 23 '15 at 00:41
  • @jfriend00 I thank you for your help! I don't think it triggers a refresh because the fields don't empty, they stay. If I do a manual refresh they disappear. Can't see any refreshes either :/ I'll keep on searching. – basickarl Sep 23 '15 at 00:49
  • Are you setting the response status to 302 on your server after setting the location header? Can you see both of these come back to the browser in the browser network tab? – jfriend00 Sep 23 '15 at 00:55
  • Do you have any sort of "no redirect" add-on installed in your browser? – jfriend00 Sep 23 '15 at 00:59
  • @jfriend00 I've been able to pin it down to client side javascript. Normal form submit without using Angular works. It's the JS (ajax) which must be stopping the refresh. – basickarl Sep 23 '15 at 12:36

1 Answers1

1

Can't believe we missed this.

When a 302 is returned from an ajax call, the browser does NOT change the current page to a new location. Instead, it fetches the contents of the new location and returns that to the Ajax call which is not what you want.

If you want the browser page to redirect after an ajax call, then you have to code that yourself in the ajax response handler in the client. I'd suggest not using a 302. Just return a normal 200 and return some JSON that tells the client what to do next. If the client gets instructions to do a redirect, then it can set window.location itself to the new URL returned in the JSON.

jfriend00
  • 683,504
  • 96
  • 985
  • 979