最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - res.redirect from an AJAX call - Stack Overflow

programmeradmin2浏览0评论

I'm trying to do a redirect after an ajax put request. I plan on using pure JS client side for validation.

Client:

$(document).ready(function() {
    login = () => {
        var username = $("[name='username']").val()
        var password = $("[name='password']").val()
        $.ajax({
            type: "put",
            url: '/login',
            data: {
                username: username,
                password: password
            }
            // success: function(response) {
            //  console.log('Success:')
            //  console.log(response.user)

            //  Cookies.set('username', response.user.username)
            //  Cookies.set('first_name', response.user.first_name)
            //  Cookies.set('last_name', response.user.last_name)
            //  Cookies.set('email', response.user.email)

            //  window.location.href = window.location.origin + '/'
            // },
            // error: function(error) {
            //  console.log("Error:")
            //  console.log(error)
            // }
        })
    }

    logout = () => {
        console.log("Log out clicked.")
        Cookies.remove('username')
        Cookies.remove('first_name')
        Cookies.remove('last_name')
        Cookies.remove('email')
        window.location.href = window.location.origin + '/logout'
    }
})

Server:

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('main')
});

router.put('/login', function(req, res) {
    // Password is not encrypted here
    console.log('req.body')
    console.log(req.body)

    User.findOne({ username: req.body.username }, function(err, user) {
        // Password is encrypted here
        if (err) throw err
        console.log('user')
        console.log(user)

        bcryptpare(req.body.password, user.password, function(err, result) {
            if (result) {
                var token = jwt.encode(user, JWT_SECRET)
                // return res.status(200).send({ user: user, token: token })
                return res.redirect('/')
            } else {
                return res.status(401).send({error: "Something is wrong."})
            }
        })
    })
})

I can't get main.hbs to render after a successful login. My commented code works, but I'm trying to do my redirect server side rather than client side because I'm told that it's better for security.

I'm trying to do a redirect after an ajax put request. I plan on using pure JS client side for validation.

Client:

$(document).ready(function() {
    login = () => {
        var username = $("[name='username']").val()
        var password = $("[name='password']").val()
        $.ajax({
            type: "put",
            url: '/login',
            data: {
                username: username,
                password: password
            }
            // success: function(response) {
            //  console.log('Success:')
            //  console.log(response.user)

            //  Cookies.set('username', response.user.username)
            //  Cookies.set('first_name', response.user.first_name)
            //  Cookies.set('last_name', response.user.last_name)
            //  Cookies.set('email', response.user.email)

            //  window.location.href = window.location.origin + '/'
            // },
            // error: function(error) {
            //  console.log("Error:")
            //  console.log(error)
            // }
        })
    }

    logout = () => {
        console.log("Log out clicked.")
        Cookies.remove('username')
        Cookies.remove('first_name')
        Cookies.remove('last_name')
        Cookies.remove('email')
        window.location.href = window.location.origin + '/logout'
    }
})

Server:

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('main')
});

router.put('/login', function(req, res) {
    // Password is not encrypted here
    console.log('req.body')
    console.log(req.body)

    User.findOne({ username: req.body.username }, function(err, user) {
        // Password is encrypted here
        if (err) throw err
        console.log('user')
        console.log(user)

        bcrypt.compare(req.body.password, user.password, function(err, result) {
            if (result) {
                var token = jwt.encode(user, JWT_SECRET)
                // return res.status(200).send({ user: user, token: token })
                return res.redirect('/')
            } else {
                return res.status(401).send({error: "Something is wrong."})
            }
        })
    })
})

I can't get main.hbs to render after a successful login. My commented code works, but I'm trying to do my redirect server side rather than client side because I'm told that it's better for security.

Share Improve this question edited May 15, 2017 at 4:15 Farid asked May 15, 2017 at 3:20 FaridFarid 1,6654 gold badges23 silver badges36 bronze badges 2
  • 2 your commented code is the correct way to work. there is no loss of security here. your redirect is communicated to user either way. server side redirect is deadend for an ajax request as the instruction is not for the browser but some javascript handler. – sbharti Commented May 15, 2017 at 3:39
  • Thanks! That's really good to know. My commented code made sense to me, and I wanted to go that direction, but I was worried about security for the user. If I'm able to use JavaScript on the client (before submitting the request to the server), I'll be able to do custom validations, rather than be limited to HTML5 form validation. – Farid Commented May 15, 2017 at 4:17
Add a comment  | 

2 Answers 2

Reset to default 11

You should know when to use href and replace functionalities.

window.location.replace(...) will best way to represent an HTTP redirect.

Reason

When compared to window.location.href, window.location.replace(...) is better to use in a HTTP redirect scenario because replace() avoids keeping the originating page in the session history, this helps users to avoid get stuck in a never-ending back-button fiasco.

Summary

If you want to illustrate clicking on a link, use location.href

If you want to illustrate an HTTP redirect, use location.replace

Sample

//  an HTTP redirect
window.location.replace("http://example.com");

//  clicking on a link
window.location.href = "http://example.com";

Update

The server cannot do a redirect from an ajax request. In the end ajax involves the client (browser).

If you want, you can send the instruction of a redirection through the server side call, but it will be end up again on client side, in the callback. You can do that by returning an object from the server which contains the url you want to redirect to. Then use javascript to change the document's location property. Like Below:

Server Side Code

if (result) {
    var token = jwt.encode(user, JWT_SECRET)
    return res.status(200).send({result: 'redirect', url:'/'})
} else {
    return res.status(401).send({error: "Something is wrong."})
}

And then in Client Side Javascript:

$.ajax({
  type: "put",
  url: '/login',
  data: {
    username: username,
    password: password
  }
  success: function(response) {
    if (response.result == 'redirect') {
      //redirecting to main page from here.
      window.location.replace(response.url);
    }

  }
});

Apart from this your commented code is the correct way to do this. Just like one of the comments in you question "server side redirect is deadend for an ajax request as the instruction is not for the browser but some javascript handler."

I don't think what you want to do is possible. An AJAX request is meant just to pass data back and forth. What happens now is that you need to script client side behavior on your end. This means the AJAX request will pass a 302 and other data that comes along for the ride to the callback on JS. No client side behavior can be altered from the server. It is up to you to do something with the AJAX returned values. If 500, throw an error message, 200 do something etc.

The only way you can get a server redirect to work is by traditional HTML form submission.

发布评论

评论列表(0)

  1. 暂无评论