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.
- 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
2 Answers
Reset to default 11You 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.