user11264239
user11264239

Reputation:

Node.js not redirecting properly

Im a beginner at using Node js. Ive developed a website with server fetching using PHP and was trying out something new. So can anyone tell me what Im doing wring here?

var mysql = require('mysql');
var express = require('express');
var session = require('express-session');
var bodyParser = require('body-parser');
var path = require('path');

var connection = mysql.createConnection({
    host    : 'localhost',
    user    : 'username',
    password: 'password',
    database: 'nodelogin'
});

var app = express();
app.use(session({
    secret: 'secret',
    resave: true,
    saveUninitialized: true
}));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

app.get('/', (request, response) => {
    response.sendFile(path.join(__dirname + '/login.html'));
});

app.post('/auth', (request, response) => {
    var username = request.body.username;
    var password = request.body.password;
    if (username && password) {
        connection.query('SELECT * FROM accounts WHERE username = ? AND password = ?', [username, password], (error, results, fields) => {
            if (results.length > 0) {
                request.session.loggedin = true;
                request.session.username = username;
                response.redirect('/home'); // This works
            } else {
                request.session.loggedin = false;
                response.send('<script>alert("Incorrect Username and/or Password!")</script>');
                response.redirect('/home'); // This doesnt work
            }
            response.end();
        });
    } else {
        response.send('Please enter Username and Password!');
        response.end();
    }
});

app.get('/home', (request, response) => {
    if (request.session.loggedin) {
        response.send('Welcome back, ' + request.session.username + '!');
    } else {
        response.send('Please login to view this page!');
    }
    response.end();
});

app.listen(3000);

Ive put up my whole app.js but after authorizing the users login, im trying to redirect to the "/home" which works in the if case but not in the else. This is after the query in the code. The error Im getting is the following, and I really cant make heads or tails of it:

C:\xampp\htdocs\students\node_modules\mysql\lib\protocol\Parser.js:437
      throw err; // Rethrow non-MySQL errors
      ^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
←[90m    at ServerResponse.setHeader (_http_outgoing.js:485:11)←[39m
    at ServerResponse.header (C:\xampp\htdocs\students\node_modules\←[4mexpress←[24m\lib\response.js:771:10)
    at ServerResponse.location (C:\xampp\htdocs\students\node_modules\←[4mexpress←[24m\lib\response.js:888:15)
    at ServerResponse.redirect (C:\xampp\htdocs\students\node_modules\←[4mexpress←[24m\lib\response.js:926:18)
    at Query.<anonymous> (C:\xampp\htdocs\students\app.js:39:26)
    at Query.<anonymous> (C:\xampp\htdocs\students\node_modules\←[4mmysql←[24m\lib\Connection.js:526:10)
    at Query._callback (C:\xampp\htdocs\students\node_modules\←[4mmysql←[24m\lib\Connection.js:488:16)
    at Query.Sequence.end (C:\xampp\htdocs\students\node_modules\←[4mmysql←[24m\lib\protocol\sequences\Sequence.js:83:24)
    at Query._handleFinalResultPacket (C:\xampp\htdocs\students\node_modules\←[4mmysql←[24m\lib\protocol\sequences\Query.js:149:8)
    at Query.EofPacket (C:\xampp\htdocs\students\node_modules\←[4mmysql←[24m\lib\protocol\sequences\Query.js:133:8) {
  code: ←[32m'ERR_HTTP_HEADERS_SENT'←[39m
}
[nodemon] app crashed - waiting for file changes before starting...

Upvotes: 1

Views: 1045

Answers (2)

Sm Srikanth
Sm Srikanth

Reputation: 2360

You are sending the response first and then trying to redirect,that is causing the error as the connection will be closed once response is sent.

Try to use 'next' middleware in the post callback like

    app.post("auth",(req,res,next)=>{
    /* Your auth logic and in the else part use next for redirection */ 

    next('redirectionRoute') 

/* Or you can keep res.redirect() and remove the res.send() in else and use appropriate route handler for the redirect route - This is better way * /
    })

Upvotes: 1

Jorge Navarro
Jorge Navarro

Reputation: 674

Here, you attempt to use res.redirect after using res.send to send an HTML string in a response. res.send comes from the Express framework and takes in data as a parameter. res.send then will then check the structure of the parameter and set the corresponding header as well as an ETag attribute in the header. It essentially implements res.write, res.setHeaders and then finally res.end, which comes from the Nodejs core and results in a "closing" of the response, effectively rendering many of the response object methods unusable since they require the response object to be "open". res.redirect is one such method that cannot be used after res.end is called (i.e. the response has been closed/is "over"). In other frameworks, a thread is dedicated to an http response and stops when the response itself has been closed. This isn't the case in Nodejs.

I would consider sending a response to the client via res.send that the client can look for as a signal to do a redirect, perhaps using something like window.location and trigger an alert.

I found these two threads to be very helpful:

Upvotes: 2

Related Questions