开发者社区> 问答> 正文

nodejs中('Can\'t set headers after they a?报错

使用nodejs和express做系统登录,先上代码:

1.login模块:

var user = require('../lib/user-model');

exports.login = function(request, response) {
    user.authenticate({
        username: request.body.username,
        password: request.body.password,
        //认证通过
        success: function(res) {
            if(res.access.token.id) {
                // 将token保存到session,然后跳转到首页
                request.session.token = res.access.token.id;
                response.redirect('home');
                return response;
            } else {
                response.render('login', {
                  errorMessage: "Server Internal Error, Try again later"});
            }
        },
        //认证失败,返回提示信息
        error: function(err) {
            response.render('login', {
                locals: { errorMessage: err.content.error.message }
            });
            return response;
        }
    });
}

2.认证模块:

var rest = require('restler');

function authenticate(options) {
    //认证服务url
    var url = 'http://200.21.0.33:5000/v2.0/tokens';
    var postBody = {
        'auth': {
            'passwordCredentials': {
                'username': options.username,
                'password': options.password
            }
        }
    };
    var data = JSON.stringify(postBody);
    var headers = {};
    headers['Content-Type'] = 'application/json';
    //发送认证请求
    rest.request(url, {
        headers : headers,
        method  : 'POST',
        data    : data,
        multipart: false,
        followRedirects: false
    }).once('success', function(data, response) {
        //成功响应后,向login模块返回成功信息
        var data = JSON.parse(data);
        options.success(data);
    })
    .once('complete', function(result, response) {
      var statusCode = (response) ? response.statusCode : 'ECONNREFUSED';
      if (result instanceof Error) {
          options.error(errorMessage(statusCode, JSON.parse(result)));
      }
      else if(!/^2\d{2}$/.test(statusCode) &&
          statusCode != 302) {
          // 认证失败,返回失败信息
          options.error(errorMessage(
              response.statusCode, JSON.parse(result)));
      }
    });
以上代码实现的功能很简单,当用户名和密码都正确时通过认证跳转到主页,认证失败则给出提示信息。

现在认证通过部分没有问题,遇到问题的地方是在认证失败给出提示信息后,若填写了正确的用户名和密码再次登录,则会报错:

throw new Error('Can\'t set headers after they are sent.');

Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:707:11)
    at ServerResponse.res.setHeader (/home/yue/workspace/vertical/node_modules/express/node_modules/connect/lib/patch.js:59:22)
    at ServerResponse.res.set.res.header (/home/yue/workspace/vertical/node_modules/express/lib/response.js:518:10)
    at ServerResponse.res.location (/home/yue/workspace/vertical/node_modules/express/lib/response.js:652:8)
    at ServerResponse.res.redirect (/home/yue/workspace/vertical/node_modules/express/lib/response.js:694:8)
    at Object.user.authenticate.success (/home/yue/workspace/vertical/routes/session.js:52:26)
    at EventEmitter.rest.request.once.once.statusCode (/home/yue/workspace/vertical/lib/test-user-model.js:145:17)
    at EventEmitter.g (events.js:175:14)
    at EventEmitter.emit (events.js:117:20)
    at EventEmitter.mixin._fireSuccess (/home/yue/workspace/vertical/node_modules/restler/lib/restler.js:205:12)


请问有什么办法解决,感谢!!!

展开
收起
爱吃鱼的程序员 2020-06-22 17:23:11 549 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    原来是使用的httpclient工具'restler'与nodejs版本的问题,改成request后就可以了

    最好把errorMessage也贴出来。
    那个错误是在你发送header头信息的时候已经有内容输出了,header头信息应该在内容输出前发送出去。

    设置hear,要在response的render之前吧?我的Node.js开源应用http://obullxl.duapp.com,用的是Express,没有自己操作response。

    2020-06-22 17:23:27
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
探究 Node.js 的服务端之路 立即下载
个推微服务实践 基于OpenResty 和Node.js 立即下载
沪江基于Node.js大规模应用实践 立即下载