简体   繁体   中英

Node.js error: 'Can't set headers after they are sent' on post

Ok, this topic as been answered a lot of times on stackoverflow, but I didn't find anything usefull for me.

I've setup a nodejs server and the 'get' queries works fine but when I'm trying to post, I get this error and it's written 'Cannot post /fr/login' (the url is domain.com/fr/login)

Just so you know, I'm using Express, i18n and Nunjucks as a templating engine.

I really don't know what's going on. I'm trying to make a login system but this is stopping me to do so. Sa bassically what's going on, is that the user input it's infos and then I call User.findOne with the mail and the password and then it should trigger the callback with the error that happen (successful login is considered an error). Currently, it does callback and 'transfer' to the callback the user information. (You might see a console.log in the callback, it is working). But when it triggers the res.render I get the two errors.

Here are my files:

  1. server.js

     app.post('/:lang/login', getChangelog, getAlert, function(req, res) { i18n.setLocale(req, req.params.lang); let version; if(req.cookies.version) { version = req.cookies.version; } if(!version) version = 0; var email = req.body.mailconnect; var password = req.body.mdpconnect; User.findOne({ email: email, password: password }, function(err, user){ if(user['error'] != "LOGIN OK") { console.log(user); errorInfo['showError'] = true; errorInfo['error-msg'] = req.__("Error-WrongMail"); res.render('login/login.njk', { title: req.__('Login-PageTitle'), style: 'login.css', alertInfo: alertInfo, errorInfo: errorInfo, version: version, currVersion: currVersion, firstVersion: firstVersion, changelog: changelog }); } else { var hash = user["mdp"]; hash = hash.replace(/^\\$2y(.+)$/i, '$2a$1'); bcrypt.compare(password, hash, function(err, res2) { if(res2){ errorInfo['showError'] = false; errorInfo['error-msg'] = "LOGIN OK"; res.redirect(i18n.getLocale + '/agent/' + user["id"] + '/selectservice'); } else{ errorInfo['showError'] = true; errorInfo['error-msg'] = req.__("Error-MailAndPassNoMatch"); res.render('login/login.njk', { title: req.__('Login-PageTitle'), style: 'login.css', alertInfo: alertInfo, errorInfo: errorInfo, version: version, currVersion: currVersion, firstVersion: firstVersion, changelog: changelog }); } }); } }); }); 
  2. user.js

     var db = require('../other/mysql.js'); exports.findOne = (data, callback) => { if(data.email != "" && data.password != "") { db.connection.query('SELECT * FROM membres WHERE mail = ?', data.email) .on('result', function (row) { let user = new Object(); user = row; user['error'] = 'WrongMail'; //Temporary, just for testing callback(null, user); }) .on('error', function (err) { let user = new Object(); user['error'] = 'SQL'; callback(err, user}); }); } } 
  3. mysql.js

     var mysql = require('mysql'); var pool = mysql.createPool({ connectionLimit : 10, host: "ip", user: "user", password: "password", database: "databse" }); exports.connection = { query: function () { var queryArgs = Array.prototype.slice.call(arguments), events = [], eventNameIndex = {}; pool.getConnection(function (err, conn) { if (err) { if (eventNameIndex.error) { eventNameIndex.error(); } } if (conn) { var q = conn.query.apply(conn, queryArgs); q.on('end', function () { conn.release(); }); events.forEach(function (args) { q.on.apply(q, args); }); } }); return { on: function (eventName, callback) { events.push(Array.prototype.slice.call(arguments)); eventNameIndex[eventName] = callback; return this; } }; } }; 
  4. This is my nodejs log

     RowDataPacket { id: 1, mail: 'mymail', matricule: '972', mdp: 'an hashed password', num_vehicle: 8001, profession: 'agent', dispatch: 'Y', supervisor: 'Y', admin: 'Y', status: 1, tkn: '3faixj17guocz89zfdx5a9', serv: '', error: 'WrongMail' } Caught exception: Error: Can't set headers after they are sent. at validateHeader (_http_outgoing.js:491:11) at ServerResponse.setHeader (_http_outgoing.js:498:3) at ServerResponse.header (F:\\GitHub\\terminal.ga\\node_modules\\express\\lib\\response.js:730:10) at ServerResponse.send (F:\\GitHub\\terminal.ga\\node_modules\\express\\lib\\response.js:170:12) at done (F:\\GitHub\\terminal.ga\\node_modules\\express\\lib\\response.js:967:10) at F:\\GitHub\\terminal.ga\\node_modules\\nunjucks\\src\\environment.js:37:5 at RawTask.call (F:\\GitHub\\terminal.ga\\node_modules\\asap\\asap.js:40:19) at flush (F:\\GitHub\\terminal.ga\\node_modules\\asap\\raw.js:50:29) at _combinedTickCallback (internal/process/next_tick.js:131:7) at process._tickCallback (internal/process/next_tick.js:180:9) 

Same issue i am facing so many times.For me this error occur two times:

  1. When I send response more than one in one callback.
  2. When I am not able to set the correct query result conditions in callback for executing other statement after getting result.

can you post also app.js with that route call only @Willbill360

I found out what was my problem. The query returned results more than on time so it was calling the callback more than one time.

To fix this, I created a new exports that just get a connection from the pool and perform a query just like in the docs. A very simpel way to be sure it does not send data more than one time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM