Reputation: 26370
I've been struggling for 2 days on this one, googled and stackoverflowed all I could, but I can't work it out.
I'm building a simple node app (+Express + Mongoose) with a login page that redirects to the home page. Here's my server JS code :
app
.get('/', (req, res) => {
console.log("Here we are : root");
return res.sendfile(__dirname + '/index.html');
})
.get('/login', (req, res) => {
console.log("Here we are : '/login'");
return res.sendfile(__dirname + '/login.html');
})
.post('/credentials', (req, res) => {
console.log("Here we are : '/credentials'");
// Some Mongoose / DB validations
return res.redirect('/');
});
The login page makes a POST request to /credentials
, where posted data is verified. This works. I can see "Here we are : '/credentials'" in the Node console.
Then comes the issue : the res.redirect doesn't work properly. I know that it does reach the '/' route, because :
(Edit) The redirection is in Mongoose's callback function, it's not synchronous (as NodeJS should be). I have just removed Mongoose validation stuff for clarity.
I have tried adding res.end()
, doesn't work
I have tried
req.method = 'get';
res.redirect('/');
and
res.writeHead(302, {location: '/'});
res.end();
Doesn't work
What am I doing wrong? How can I actually leave the '/login' page, redirect the browser to '/' and display the HTML code that it received?
Thanks a million for your help in advance :)
Upvotes: 39
Views: 83591
Reputation: 1608
I know this is older and the upvoted answers are indeed useful; I just wanted to take it one step further and show what I do when calling my api with a JavaScript fetch
call.
Assuming my backend does a res.redirect('/newpage')
; the frontend checks the redirected
flag in the response and if true, go to the redirected url:
Backend (node.js express)
router.get('/oldpage', function(req, res) {
res.redirect('/newpage');
});
Frontend (JavaScript)
const api = await fetch('/oldpage');
if (api.redirected) {
window.location.href = api.url;
}
I don't know if this is the best solution but checking for redirected
and then applying the url has been working fine for me.
Upvotes: 0
Reputation: 61
If you are using an asynchronous request to backend and then redirecting in backend, it will redirect in backend (i.e. it will create a new get request to that URL), but won't change the URL in front end.
To make it work you need to:
window.location.href = "/url"
<a></a>
)Upvotes: 6
Reputation: 63
I've been working on implementing nodemailer into my NextJS app with Express. Was having this issue and came across this. I had event.preventDefault() in my function that was firing the form to submit and that was preventing the redirect as well, I took it off and it was redirecting accordingly.
Upvotes: 0
Reputation: 588
The problem might not lie with the backend, but with the frontend. If you are using AJAX to send the POST request, it is specifically designed to not change your url.
Use window.location.href
after AJAX's request has completed (in the .done()
) to update the URL with the desired path, or use JQuery: $('body').replaceWith(data)
when you receive the HTML back from the request.
Upvotes: 57
Reputation: 4678
Add the following in your get / route :
res.setHeader("Content-Type", "text/html")
Your browser will render file instead of downloading it
Upvotes: -2
Reputation: 11980
It's almost certain that you are making an async call to check Mongoose but you haven't structured the code so that the redirect only happens after the async call returns a result.
In javascript, the POST
would look like something this:
function validateCredentials(user, callback){
// takes whatever you need to validate the visitor as `user`
// uses the `callback` when the results return from Mongoose
}
app.post('/credentials', function(req, res){
console.log("Here was are: '/credentials'";
validateCredentials(userdata, function(err, data){
if (err) {
// handle error and redirect to credentials,
// display an error page, or whatever you want to do here...
}
// if no error, redirect
res.redirect('/');
};
};
You can also see questions like Async call in node.js vs. mongoose for parallel/related problems...
Upvotes: 0