Node.js错误:'发送后无法设置标头'在帖子上

时间:2018-06-14 03:59:36

标签: javascript node.js express post nunjucks

好的,这个主题已经在stackoverflow上得到了很多次的回答,但我没有找到对我有用的东西。

我已经设置了一个nodejs服务器并且' get'查询工作正常,但是当我尝试发帖时,我收到此错误并且已写入“无法发布/ fr /登录”#39; (网址为domain.com/fr/login)

您知道,我使用Express,i18n和Nunjucks作为模板引擎。

我真的不知道发生了什么。我试图建立登录系统,但这阻止了我这样做。用贝司的方式进行的是,用户输入它的信息,然后用邮件和密码调用User.findOne然后它应该触发回调并发生错误(成功)登录被视为错误)。目前,它确实回调和转移'回调用户信息。 (您可能会在回调中看到console.log,它正在运行)。但当它触发res.render时,我得到了两个错误。

以下是我的文件:

  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. 这是我的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)
    

2 个答案:

答案 0 :(得分:0)

同样的问题我面临很多次。对我来说,这个错误会发生两次:

  1. 当我发送多个回调的响应时。
  2. 当我无法在回调中设置正确的查询结果条件,以便在获得结果后执行其他语句。
  3. 你能用@ Willbill360

    发布那个路由呼叫的app.js吗?

答案 1 :(得分:0)

我发现了我的问题。查询返回的结果超过了时间,所以它多次调用回调。

为了解决这个问题,我创建了一个新的导出,它只是从池中获取连接并执行查询,就像在文档中一样。一种非常简单的方法,可以确保它不会多次发送数据。