我对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);

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


很多人都犯过这个错误。这与异步处理很容易混淆。最有可能的是,你的一些代码在第一个tick设置头,然后你在未来的tick运行一个异步回调。在此期间,响应头被发送,但随后进一步的头(如30X重定向)尝试添加额外的头,但为时已晚,因为响应头已经被传输。

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

简化代码的一个简单技巧。去掉app.configure(),直接在顶层作用域调用app.use。

请参见everyauth模块,该模块用于Facebook和十几个其他第三方身份验证提供商。


Express中的res对象是Node.js的http的子类。ServerResponse(读取http.js源代码)。你可以调用res.setHeader(name, value),直到你调用res.writeHead(statusCode)。在writeHead之后,头被烘焙进去,你只能调用res.write(data),最后调用res.end(data)。

错误“错误:发送后无法设置报头”意味着您已经处于Body或Finished状态,但某些函数试图设置报头或statusCode。当您看到此错误时,请尝试查找在已经写入部分正文之后试图发送头的任何内容。例如,查找意外调用两次的回调,或者在正文发送之后发生的任何错误。

在您的示例中,您调用了res.redirect(),这导致响应变为Finished。然后你的代码抛出一个错误(res.req是null)。并且由于错误发生在您的实际函数(req, res, next)(而不是回调函数)中,Connect能够捕获它,然后尝试发送一个500错误页面。但是由于头已经发送,Node.js的setHeader抛出了你所看到的错误。

Node.js/Express响应方法的综合列表,以及何时必须调用它们:

响应必须在头部,并保持在头部:

res.writeContinue () res.statusCode = 404 res.setHeader(名称、值) res.getHeader(名字) res.removeHeader(名字) res.header(key[, val]) res.charset = 'utf-8'(仅限Express;只影响特定于express的方法) res.contentType(类型)(仅适用于Express)

Response必须在Head中并成为Body:

作家(雕像,[原因],[标题])

Response可以在Head/Body中任意一个,并保留在Body中:

res.write (chunk, encoding =‘utf8)

Response可以在Head/Body中任意一个,变成Finished:

res.end((数据),(编码))

响应可以在Head/Body中任意一个,并保持当前状态:

res.addTrailers(头)

响应必须在头部,成为完成:

return next([err]) (Connect/Express only) Any exceptions within middleware function(req, res, next) (Connect/Express only) res.send(body|status[, headers|status[, status]]) (Express only) res.attachment(filename) (Express only) res.sendfile(path[, options[, callback]]) (Express only) res.json(obj[, headers|status[, status]]) (Express only) res.redirect(url[, status]) (Express only) res.cookie(name, val[, options]) (Express only) res.clearCookie(name[, options]) (Express only) res.render(view[, options[, fn]]) (Express only) res.partial(view[, options]) (Express only)


有一段时间我也遇到了这个错误。我想(希望)我已经想明白了,想把它写在这里供参考。

当你使用app.use方法添加中间件来连接或表达(建立在connect上)时,你在connect中将项目附加到Server.prototype.stack中(至少在当前的npm install connect中,它看起来与本文的github有很大不同)。当服务器收到请求时,它遍历堆栈,调用(request, response, next)方法。

问题是,如果在一个中间件项目中写入响应体或报头(出于某种原因,它看起来像是/或),但没有调用response.end(),而是调用next(),然后作为核心Server.prototype.handle方法完成,它将注意到:

堆栈中没有更多的项,和/或 这种反应。headerSent为true。

因此,它抛出一个错误。但是它抛出的错误只是这个基本的响应(来自connect http.js源代码:

res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain');
res.end('Cannot ' + req.method + ' ' + req.url);

就在那里,它调用res.setHeader('Content-Type', 'text/plain');,你可能已经在你的渲染方法中设置了,而没有调用response.end(),类似于:

response.setHeader("Content-Type", "text/html");
response.write("<p>Hello World</p>");

所有东西的结构是这样的:

良好的中间件

// middleware that does not modify the response body
var doesNotModifyBody = function(request, response, next) {
  request.params = {
    a: "b"
  };
  // calls next because it hasn't modified the header
  next();
};

// middleware that modify the response body
var doesModifyBody = function(request, response, next) {
  response.setHeader("Content-Type", "text/html");
  response.write("<p>Hello World</p>");
  response.end();
  // doesn't call next()
};

app.use(doesNotModifyBody);
app.use(doesModifyBody);

有问题的中间件

var problemMiddleware = function(request, response, next) {
  response.setHeader("Content-Type", "text/html");
  response.write("<p>Hello World</p>");
  next();
};

有问题的中间件设置响应头时没有调用response.end(),而是调用next(),这会混淆connect的服务器。


在我的案例中,是304响应(缓存)导致了这个问题。

最简单的解决方案:

app.disable('etag');

如果你想要更多的控制,这里有另一个解决方案:

http://vlasenko.org/2011/10/12/expressconnect-static-set-last-modified-to-now-to-avoid-304-not-modified/


我也有同样的问题,并意识到这是因为我调用res.redirect时没有返回语句,所以下一个函数也被立即调用:

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();
};

对于任何遇到这种情况的人来说,其他解决方案都没有帮助,在我的情况下,这在处理图像上传但不处理超时的路由上表现出来,因此,如果上传花费了太长时间并超时,当回调在超时响应发送后被触发时,调用res.send()会导致崩溃,因为报头已经设置为考虑超时。

这很容易通过设置一个非常短的超时和撞击路线与一个相当大的图像再现,每次崩溃都被再现。


在我的情况下,这发生在React和post .js中,当我没有从我的React组件的componentWillUnmount回调中的通道中取消订阅时。


我在这个问题上绞尽脑汁,它是由于处理回调时的一个粗心错误而发生的。不返回的回调将导致设置两次响应。

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

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

发生的事情是:在验证失败的情况下,回调被调用,响应被设置。但没有回来。所以它仍然继续这个方法到db并点击success/failure。它再次调用相同的回调,导致现在设置两次响应。

所以解决方案很简单,你需要“返回”回调,这样方法就不会继续执行,一旦错误发生,因此设置响应对象一次

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

就靠这个。你可以通过这个函数传递响应:

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();
});

当您在发送响应后传递语句时将遇到这种类型的错误。

例如:

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

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

如果你想做任何事情,你应该在发送响应之前做。


有时,当你试图在res.end或res.send之后调用next()函数时,你可能会得到这个错误,如果你在函数中res.send或res.end之后调用next(),请尝试删除。 注意:这里的next()表示在响应客户端后(i。E res.send或res.end)你仍然试图执行一些代码来再次响应,所以这是不合法的。

例子:

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

从上面的函数中删除next(),它将工作。


添加这个中间件就可以工作了

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();
});

这种情况发生在响应传递给客户端时,您再次尝试给出响应。你必须检查你的代码,在某个地方,你返回的响应客户端再次导致这个错误。当您想返回时,检查并返回响应一次。


这个问答中的一些答案是错误的。公认的答案也不是很“实用”,所以我想发布一个答案,用更简单的术语解释事情。我的答案将涵盖99%我看到的反复发布的错误。对于错误背后的实际原因,请查看公认的答案。


HTTP使用一个周期,每个请求需要一个响应。当客户端发送一个请求(例如POST或GET)时,服务器应该只向它发送一个响应。

这个错误信息:

错误:发送后不能设置报头。

通常发生在为一个请求发送多个响应时。确保下列函数在每个请求中只被调用一次:

res.json () res.send () res.redirect () res.render ()

(还有一些很少使用的,检查被接受的答案)

当这些res函数被调用时,路由回调将不会返回。它将继续运行,直到到达函数或return语句的末尾。如果你想在发送响应时返回,你可以这样做:返回res.send()。


以下面的代码为例:

app.post('/api/route1', function(req, res) {
  console.log('this ran');
  res.status(200).json({ message: 'ok' });
  console.log('this ran too');
  res.status(200).json({ message: 'ok' });
}

当POST请求被发送到/api/route1时,它将运行回调中的每一行。由于res.json()被调用了两次,这意味着发送了两个响应,因此将抛出一个不能设置报头的错误消息。

每个请求只能发送一个响应!


上面的代码示例中的错误很明显。一个更典型的问题是当你有几个分支时:

app.get('/api/company/:companyId', function(req, res) {
  const { companyId } = req.params;
  Company.findById(companyId).exec((err, company) => {
      if (err) {
        res.status(500).json(err);
      } else if (!company) {
        res.status(404).json();      // This runs.
      }
      res.status(200).json(company); // This runs as well.
    });
}

这个带有附加回调的路由在数据库中查找公司。当对一个不存在的公司进行查询时,我们将进入else if分支并发送404响应。在此之后,我们将继续到下一个语句,该语句也发送响应。现在我们已经发送了两个响应,将会出现错误消息。我们可以通过确保只发送一个响应来修复这段代码:

.exec((err, company) => {
  if (err) {
    res.status(500).json(err);
  } else if (!company) {
    res.status(404).json();         // Only this runs.
  } else {
    res.status(200).json(company);
  }
});

或者在发送响应时返回:

.exec((err, company) => {
  if (err) {
    return res.status(500).json(err);
  } else if (!company) {
    return res.status(404).json();  // Only this runs.
  }
  return res.status(200).json(company);
});

一个大罪人是异步函数。以这个问题中的函数为例:

article.save(function(err, doc1) {
  if (err) {
    res.send(err);
  } else {
    User.findOneAndUpdate({ _id: req.user._id }, { $push: { article: doc._id } })
    .exec(function(err, doc2) {
      if (err) res.send(err);
      else     res.json(doc2);  // Will be called second.
    })

    res.json(doc1);             // Will be called first.
  }
});

在代码示例中,我们有一个异步函数(findOneAndUpdate())。如果没有错误(err),将调用findOneAndUpdate()。因为这个函数是异步的,所以res.json(doc1)将被立即调用。假设findOneAndUpdate()中没有错误。else中的res.json(doc2)将被调用。现在已经发送了两个响应,并且出现了“不能设置标题”错误消息。

在这种情况下,修复方法是删除res.json(doc1)。为了将两个文档都发送回客户端,else中的res.json()可以写成res.json({article: doc1, user: doc2})。


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

WebSocket.on("message", (data) => {
    receivedMessage = true;
    doSomething(data);
    localSocket.close(); //This close the connection, allowing 
});

如果你没有得到上面的帮助:新手 这个错误背后的原因是多次发送请求,让我们从一些情况下理解:- 1. `

module.exports = (req,res,next)=>{
        try{
           const decoded  = jwt.verify(req.body.token,"secret");
           req.userData = decoded;
           next();
        }catch(error){
            return res.status(401).json({message:'Auth failed'});
        }
        next();   
        }

` 在上面的例子中,两次调用next()将引发一个错误

router.delete('/:orderId', (req, res, next) => { Order.remove({_id:req.params.orderId},(err,data)=>{ if(err){ **res.status(500).json(err);** }else{ res.status(200).json(data); } *res.status(200).json(data);* }) })

这里的响应是发送两次,检查是否已经发送了响应


我在做承诺的时候也有这个问题。promise内部的promise将向服务器返回200,但外部promise的catch语句将返回500。一旦我解决了这个问题,问题就消失了。


在我的例子中,这是由于多次回调造成的。在代码期间,我多次调用next()方法


从nuxt来到这里,问题是在组件的asyncData方法,我忘记返回承诺,这是获取数据和设置头在那里。


为了防止出现这种错误,我所要做的就是res.end()。

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

你可能面临的另一个问题是在res.json和res. write之后还有代码。在这种情况下,您需要使用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 
};

请检查您的代码是否为单个请求返回多个res.send()语句。就像当我有这个问题....

我在我的restify节点应用程序中遇到了这个问题。错误在于

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

我在不间断的情况下使用开关处理各种情况。对于那些稍微熟悉开关情况的人都知道,不间断,返回关键字。case下的代码和它的下一行都将被执行。虽然我想发送单个res。send,但由于这个错误它返回了多个res。send语句,这提示

错误:不能设置头后,他们被发送到客户端。

通过添加这个或在每个res.send()方法之前使用return来解决,比如return res.send(200)

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

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


如果你正在使用回调函数,请在err块之后使用return。这是可能发生此错误的场景之一。

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和express 4.16.4上进行测试


当您发送2个响应时发生此错误。例如:

if(condition A)
{ 

      res.render('Profile', {client:client_});

}

if (condition B){

      res.render('Profile', {client:client_});
    }
  }

想象一下,如果由于某种原因,条件A和B为真,那么在第二次渲染中,你会得到这个错误


当我试图在循环函数内发送响应时,我得到了类似的错误。最简单的解决办法就是移动

res.send(发送响应的);

退出循环,因为你只能发送一次响应头。

https://www.tutorialspoint.com/nodejs/nodejs_response_object.htm


我简单地添加了return关键字: 返回res.redirect(“/”);它成功了!


在RND后自行查找错误:

1)我的错误代码:

返回res.sendStatus(200)。Json ({data: result});

2)我的成功密码

返回res.status(200)。Json ({data: result});

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


我的问题是我有一个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之前就可以了。


我也有同样的问题,是猫鼬引起的。

为了解决这个问题,你必须启用承诺,所以你可以添加:猫鼬。承诺=全球。承诺你的代码,这使得使用原生js承诺。

这个解决方案的其他替代方案是:

var mongoose = require('mongoose');
// set Promise provider to bluebird
mongoose.Promise = require('bluebird');

and

// q
mongoose.Promise = require('q').Promise;

但是您需要先安装这些包。


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


还有其他原因导致了这个错误,它是当你没有在res.send, res.json等前面添加return关键字时……


的过程。Env不会改变,因此它不能用于访问每个请求的环境变量,这些变量的值可能会根据每个请求而改变。 因此,如果用户生成了一个应用程序进程,但不是作为处理请求的一部分,那么该应用程序进程将不会在操作系统级环境变量中存储每个请求的环境变量。 因此,使用这段代码存储进程env,程序就可以成功运行。

    const port = process.env.PORT || 2000;
    
    app.listen(port,()=>{
        console.log("Server running at port 2000");
    })

请在你的app.get中搜索是否在res.send(“你的结果”)之前没有设置状态;

我只是删除了:

res.sendStatus(200);

在那之后,反应是有效的!!

res.send("your result");

In my case, this is recurring when I don't make a function that is running against a mongodb schema an async function like this technicianAuthSchema.methods.matchPasswords = function(password) { return await bcrypt.compare( password, this.password ); }; I get this Logged error: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client instead of technicianAuthSchema.methods.matchPasswords = async function(password) { return await bcrypt.compare( password, this.password ); }; It is asynchronous because the this.password is coming from the object this function is running against which we are pulling from the database.


检查代码。对我来说,我在同一个if语句中两次使用res.status。第一个设置了报头状态,第二个试图改变它,这导致了问题。


问题是从/auth/facebook路由存在的,为了让事情更容易理解,一旦你已经从客户端发送了一个响应,你就不能为下一个后续块设置任何其他函数,这也与JavaScript的同步有关。

为了更深入地理解,它看起来像这样的代码;

async function getRequest(){
   let data = await API.get();
   return data;
   let json = data.json(); // will not read this line
}

在你的案例中,console.log("ok cool.");console.log(res['req']['session'])必须放在res.redirect("/great")之前

希望这是有意义的,欢迎:)


如果在一个api调用中使用了两个res.end()函数,则会出现此错误

例如

  app.post("/auth", function (request, res) {
    var username = request.body.username;
    var password = request.body.password;
    if (username && password) {
      let sql =
        "SELECT username, worker_name, worker_surname, id FROM workers where username = ? AND password=?";
      con.query(sql, [username, password], function (error, results, fields) {
        if (results.length > 0) {
          res.status(200).send(results);
          res.end();
  
        }
        res.status(404).send("Incorrect Username and/or Password!");
      });
    } else {
      res.send("Please enter Username and Password!");
    }
    res.end();

  });

Node的新版本支持res.headersSent布尔表达式。你可以用它来验证你是否已经发送了一个响应:

if (!res.headersSent) // if doesn't sent yet
    res.status(200).send({ "message": "This is a message" })

注意!虽然这可以工作并回答问题,但这不是解决问题的正确方法,不推荐!

多次发送响应表明代码中存在问题,需要修复(这与在函数中一个接一个地使用两个return语句是一样的。这是一个bug)。


我遇到了问题 这就是我在做的

const user  = await User.findOne({_id: req.params.id})

所以我不得不改变findOne到findById,它为我做的伎俩

const user = await User.findById(req.params.id)

我得到了同样的错误,并发现我的解决方案是将所有sendStatus代码行更改为status。

// old
res.sendStatus(200);

// new 
res.status(200);

有时只是写作 res.status(200)。Json ({success: 'user authenticated'); 还不够。 几个小时后,我发现我们有时必须返回返回响应。 像这样

返回res.status(200)。Json ({success: 'user authenticated');

这样它就可以在任何条件语句中终止,而不运行其他语句。


在我的例子中,它是一个全局拦截器,设置无缓存头。


显然,这种情况的发生有多种原因。很多情况都很复杂,但我的情况是一个相当简单的错误。

检查是否使用了正确的表单方法。默认值是GET,我忘记指定了。可以想象,我的GET路由逻辑在处理请求时做得很差。主体数据被设计为由我的POST路由逻辑解析。


在我的例子中,我必须在响应上添加Promise的.then()方法。所以我的代码如下所示:

 app.post(`${api}/categories`, (req, res) => {
const category = new Category({
    ....
});
category.save().then(c => {
    res.status(201).json(c)
}).catch((err) => {
    res.status(500).json({
        ...
    })
});

})


我面对这个错误了几天,发现是我的jwt过期了,在这种情况下,它不能设置头文件。

检查你的JWT的有效期


我在使用邮递员时也犯了同样的错误。我注意到请求体(数据)的格式不正确。错误指向我在路由中传递的中间件。当我删除一个中间件时,它就意味着删除下一个中间件。


我也有同样的问题。对我来说,我有2 res.json(事件)给我这个错误。

res.json(savedEvent);
res.json({ event });

我们应该通过只有单一的反应才会起作用。

res.json(event);