错误:将标头发送到客户端后无法设置标头

我对Node.js相当陌生,遇到了一些问题。

我正在使用Node.js 4.10和Express 2.4.3。

当我尝试访问http://127.0.0.1:8888/auth/facebook时,我将重定向到http://127.0.0.1:8888/auth/facebook_callback

然后,我收到以下错误:

Error: Can't render headers after they are sent to the client.
    at ServerResponse.<anonymous> (http.js:573:11)
    at ServerResponse._renderHeaders (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:64:25)
    at ServerResponse.writeHead (http.js:813:20)
    at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/auth.strategies/facebook.js:28:15
    at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:113:13
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/strategyExecutor.js:45:39)
    at [object Object].pass (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/authExecutionScope.js:32:3)
    at [object Object].halt (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/authExecutionScope.js:29:8)
    at [object Object].redirect (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/authExecutionScope.js:16:8)
    at [object Object].<anonymous> (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/auth.strategies/facebook.js:77:15)
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:195:11)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:150:23)
    at param (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:189:13)
    at pass (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:191:10)
    at Object.router [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:197:6)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15)
    at Object.auth [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:153:7)
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:207:9)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:150:23)
    at param (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:189:13)
    at pass (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:191:10)
    at Object.router [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/router.js:197:6)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15)
    at Object.auth [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:153:7)
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:150:23)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:207:9)
    at Object.auth [as handle] (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:153:7)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15)
    at HTTPServer.handle (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:211:3)
    at Object.handle (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:105:14)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15)
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:150:23)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:207:9)
    at HTTPServer.handle (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:211:3)
    at Object.handle (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:105:14)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:198:15)
    at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:323:9
    at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:338:9

node.js:134
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
Error: Can't set headers after they are sent.
    at ServerResponse.<anonymous> (http.js:527:11)
    at ServerResponse.setHeader (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/patch.js:50:20)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:162:13)
    at next (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/http.js:207:9)
    at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:323:9
    at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:338:9
    at Array.<anonymous> (/home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session/memory.js:57:7)
    at EventEmitter._tickCallback (node.js:126:26)

以下是我的代码:

var fbId= "XXX";
var fbSecret= "XXXXXX";
var fbCallbackAddress= "http://127.0.0.1:8888/auth/facebook_callback"

var cookieSecret = "node";     // enter a random hash for security

var express= require('express');
var auth = require('connect-auth')
var app = express.createServer();


app.configure(function(){
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser());
    app.use(express.session({secret: cookieSecret}));
    app.use(auth([
        auth.Facebook({
            appId : fbId,
            appSecret: fbSecret,
            callback: fbCallbackAddress,
            scope: 'offline_access,email,user_about_me,user_activities,manage_pages,publish_stream',
            failedUri: '/noauth'
        })
    ]));
    app.use(app.router);
});


app.get('/auth/facebook', function(req, res) {
  req.authenticate("facebook", function(error, authenticated) {
    if (authenticated) {
      res.redirect("/great");
      console.log("ok cool.");
      console.log(res['req']['session']);
    }
  });
});

app.get('/noauth', function(req, res) {
  console.log('Authentication Failed');
  res.send('Authentication Failed');
});

app.get('/great', function( req, res) {
  res.send('Supercoolstuff');
});

app.listen(8888);

我可以知道我的代码有什么问题吗?

阿飞米亚2020/03/11 15:09:06

如果发生此错误,我要做的就是res.end()。

 auth.annonymousOnly = function(req, res, next) {
 // add other task here   
   res.end();    
  };

您可能面临的另一个问题是res.json和res之后有代码。写。在这种情况下,此后您需要使用return停止执行。

 auth.annonymousOnly = function(req, res, next) {

  if(!req.body.name)
  {
    res.json({error:"some error"});
    return;
  }
  let comp = "value"; // this is the code after res.json which may cause some problems so you have to use return 
};
卡卡西神奇2020/03/11 15:09:06

在我的情况下,我放置了一个循环,res.render()因此可能已尝试多次调用。

神奇小小2020/03/11 15:09:06

在RND之后错误自行查找:

1)我的错误代码:

return res.sendStatus(200).json({ data: result });

2)我的成功代码

return res.status(200).json({ data: result });

区别在于我使用了sendStatus()而不是status()

Davaid神无2020/03/11 15:09:06

我的问题是我有一个setInterval正在运行的程序,该程序有一个if/else块,其中该clearInterval方法位于内else

      const dataExistsInterval = setInterval(async () => {
        const dataExists = Object.keys(req.body).length !== 0;
        if (dataExists) {
          if (!req.files.length) {
            return res.json({ msg: false });
          } else {
              clearInterval(dataExistsInterval);
            try {
            . . .

把把clearInterval之前if/else的把戏。

ItachiHarry2020/03/11 15:09:06

我只需添加返回关键字,例如: return res.redirect("/great");和walla!

十三西里古一2020/03/11 15:09:06

就我而言,它是由于多个回调而发生的。next()在代码中多次调用了方法

小胖GO2020/03/11 15:09:06

请检查您的代码是否针对单个请求返回多个res.send()语句。就像我遇到这个问题时一样...

我在我的Restify节点应用程序中就是这个问题。错误是

switch (status) { case -1: res.send(400); case 0: res.send(200); default: res.send(500); }

我正在使用switch处理各种情况,而没有写中断。对于那些不太熟悉switch情况的人来说,知道不间断地返回关键字。大小写及其下一行的代码无论如何都将执行。因此,即使我要发送单个res.send,由于此错误,它仍会返回多个res.send语句,这提示

将标头发送到客户端后,无法设置标头。通过在每个res.send()方法(例如return res.send(200))之前添加此内容或使用return可以解决该问题

switch (status) { case -1: res.send(400); break; case 0: res.send(200); break; default: res.send(500); break; }

逆天蛋蛋达蒙2020/03/11 15:09:06

在Typescript中,我的问题是收到消息后我没有关闭websocket连接。

WebSocket.on("message", (data) => {
    receivedMessage = true;
    doSomething(data);
    localSocket.close(); //This close the connection, allowing 
});
Stafan卡卡西2020/03/11 15:09:06

这很可能是节点的事情,在99%的时间内,它是一个双重回调,导致您响应两次,或者next()响应两次,等等,该死。它解决了我的问题是在循环内使用next()。从循环中删除next()或停止多次调用它。

Davaid阳光小卤蛋2020/03/11 15:09:06

nuxt来到这里,问题出在组件的asyncData方法中,我忘了return保证这是在获取数据并在其中设置标头。

StafanDavaid2020/03/11 15:09:06

当响应已传递给客户端,并且您再次尝试给出响应时,就会发生这种情况。您必须检入代码,确认您正在某个地方再次将响应返回给客户端,这会导致此错误。要返回时,请检查并返回一次响应。

西里伽罗2020/03/11 15:09:06

我嵌套诺言时遇到了这个问题。一个内部的Promise将向服务器返回200,但是外部的Promise的catch语句将返回500。一旦我解决了这个问题,问题就消失了。

罗静云2020/03/11 15:09:06

添加此中间件,它将起作用

app.use(function(req,res,next){
 var _send = res.send;
var sent = false;
res.send = function(data){
    if(sent) return;
    _send.bind(res)(data);
    sent = true;
};
next();
});
凯LEY2020/03/11 15:09:06

只是靠这个。您可以通过以下函数传递响应:

app.use(function(req,res,next){
  var _send = res.send;
  var sent = false;
  res.send = function(data){
    if(sent) return;
    _send.bind(res)(data);
    sent = true;
};
  next();
});
泡芙Green2020/03/11 15:09:06

对于要解决此问题的人,其他解决方案都无济于事,就我而言,这体现在处理图像上传但不处理超时的路由上,因此,如果上载时间太长且超时,则触发回调时发送超时响应后,调用res.send()导致崩溃,因为标头已设置为解决超时问题。

通过设置非常短的超时并以相当大的图像击中路线,可以轻松地重现该崩溃,每次都崩溃。

十三LEY2020/03/11 15:09:06

就我而言,这发生在React和postal.js上,当时我没有在componentWillUnmountReact组件回调中退订通道

老丝乐2020/03/11 15:09:06

如果使用回调函数,请使用 return after the err block. This is one of the scenarios in which this error can happen.

userModel.createUser(data, function(err, data) {
    if(err) {
      res.status = 422
      res.json(err)
      return // without this return the error can happen.
    }
    return res.json(data)
  })

在Node版本上测试v10.16.0并表示4.16.4

Eva西里2020/03/11 15:09:06

有时,在尝试在res.endres.send之后调用next()函数时可能会遇到此错误,如果函数中在res.send或res.end之后有next(),则尝试删除。注意:这里的next()意味着在使用您的响应(即res.send或res.end响应客户端之后,您仍在尝试执行一些代码以再次响应,因此这是不合法的。

范例:

router.get('/',function (req,res,next){
     res.send("request received");
     next(); // this will give you the above exception 
});

去掉 next()从上述功能中,它将起作用。

梅十三Near2020/03/11 15:09:06

在发送响应后传递语句时,您将获得此类型的错误。

例如:

res.send("something response");
console.log("jhgfjhgsdhgfsdf");
console.log("sdgsdfhdgfdhgsdf");
res.send("sopmething response");

将导致您看到的错误,因为一旦发送了响应,res.send将不会执行以下操作

如果要执行任何操作,则应在发送响应之前执行此操作。

村村L2020/03/11 15:09:06

很多人遇到此错误。这与异步处理混淆了。您的某些代码很可能在第一个刻度中设置了标头,然后在以后的刻度中运行了异步回调。在此之间,将发送响应头,但随后的头(例如30X重定向)会尝试添加额外的头,但是由于已经发送了响应头,为时已晚。

我不确定是什么导致了您的错误,但是请把所有回调作为潜在的研究领域。

一个简单的技巧来简化您的代码。摆脱掉,直接在您的顶级示波器中app.configure()调用app.use即可。

另请参阅everyauth模块,该模块执行Facebook和大约十二个其他第三方身份验证提供程序。

小哥梅2020/03/11 15:09:06

我为解决这个问题付出了很多精力,但由于处理回调时出现了一个粗心的错误,所以发生了这种情况。非返回的回调导致将响应设置两次。

我的程序有一个验证请求并查询数据库的代码。验证是否存在错误后,我使用验证错误回调了index.js。如果验证通过,它将继续执行并成功/失败进入数据库。

    var error = validateRequestDetails("create",queryReq);
    if (error)
        callback(error, null);
   else
    some code 
    callback(null, success);

发生的事情是:如果验证失败,则将调用回调并设置响应。但是没有回来。因此它仍然继续,该方法转到db并命中成功/失败。它再次调用相同的回调,导致现在将响应设置两次。

因此解决方案很简单,一旦发生错误,您需要“返回”回调,以使该方法不再继续执行,因此只需设置一次响应对象

  var error = validateRequestDetails("create",queryReq);
    if (error)
        callback(error, null);
        return;
    else
       some code 
       callback(null, success);
十三蛋蛋2020/03/11 15:09:06

我遇到了同样的问题,并意识到这是因为我在res.redirect没有return声明的情况下进行调用,所以next此后函数也立即被调用:

auth.annonymousOnly = function(req, res, next) {
    if (req.user) res.redirect('/');
    next();
};

应该是:

auth.annonymousOnly = function(req, res, next) {
    if (req.user) return res.redirect('/');
    next();
};