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

我对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:15at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect-auth/lib/index.js:113:13at 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:9at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:338:9
node.js:134throw 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:9at /home/eugene/public_html/all_things_node/projects/fb2/node_modules/connect/lib/middleware/session.js:338:9at 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);

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

1688891 次浏览

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

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

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

另请参阅everyauth模块,该模块负责Facebook和十几个其他第三方身份验证提供商。

Express中的res对象是node . js的# 1(读取http.js源代码)的子类。你可以随时拨打res.setHeader(name, value),直到拨打res.writeHead(statusCode)。在writeHead之后,头文件被烘焙,你只能调用res.write(data),最后是res.end(data)

错误“错误:发送头文件后不能设置头文件”;意思是你已经在Body或Finished状态,但是一些函数试图设置一个头或statusCode。当您看到此错误时,请尝试查找在已经写入部分正文之后试图发送头的任何内容。例如,查找意外调用两次的回调,或者在正文发送之后发生的任何错误。

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

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

响应必须在中并保持在中:

  1. res.writeContinue()
  2. res.statusCode = 404
  3. res.setHeader(name, value)
  4. res.getHeader(name)
  5. res.removeHeader(name)
  6. # 0(仅限快递)
  7. res.charset = 'utf-8'(仅限快递;只影响特定于express的方法)
  8. # 0(仅限快递)

响应必须在,变成身体:

  1. res.writeHead(statusCode, [reasonPhrase], [headers])

响应可以是头/身体,也可以是身体:

  1. res.write(chunk, encoding='utf8')

响应可以是头/身体,也可以是完成了:

  1. res.end([data], [encoding])

响应可以是头/身体,并保持当前状态:

  1. res.addTrailers(headers)

响应必须在,变成完成了:

  1. return next([err])(仅限连接/快速)
  2. 中间件function(req, res, next)中的任何异常(仅限Connect/Express)
  3. # 0(仅限快递)
  4. # 0(仅限快递)
  5. # 0(仅限快递)
  6. # 0(仅限快递)
  7. # 0(仅限快递)
  8. # 0(仅限快递)
  9. # 0(仅限快递)
  10. # 0(仅限快递)
  11. # 0(仅限快递)

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

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

问题是,如果在一个中间件项目中写入响应体或报头(出于某种原因,它看起来不是/就是),但不是呼叫#0,而是呼叫#1,然后当核心Server.prototype.handle方法完成时,它会注意到:

  1. 堆栈中没有更多的项,和/或
  2. 0是正确的。

因此,它抛出一个错误。但它抛出的错误只是这个基本的响应(来自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');,你可能已经在render方法不调用response.end()中设置过了,比如:

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

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

良好的中间件

// middleware that does not modify the response bodyvar doesNotModifyBody = function(request, response, next) {request.params = {a: "b"};// calls next because it hasn't modified the headernext();};
// middleware that modify the response bodyvar 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/

我也有同样的问题,并意识到这是因为我在没有return语句的情况下调用了res.redirect,所以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();};

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

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

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

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

我的程序有一个验证请求和查询DB的代码。在验证错误是否存在后,我用验证错误回调index.js。如果验证通过,它将继续执行,并以成功/失败来撞击db。< / p >
    var error = validateRequestDetails("create",queryReq);if (error)callback(error, null);elsesome codecallback(null, success);

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

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

  var error = validateRequestDetails("create",queryReq);if (error)callback(error, null);return;elsesome codecallback(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.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(),它将工作。

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

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)时,服务器应该只向它发送一个响应。

这个错误信息:

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

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

  • # 0
  • # 0
  • # 0
  • # 0

(以及一些很少使用的,检查接受的答案)

当这些res函数被调用时,路由回调将不会返回。它将继续运行,直到到达函数或return语句的末尾。如果你想在发送响应时返回,你可以这样做: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);});

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

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. ' < / p >

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();}
< p > '在上面的例子中,两次调用next()将引发一个

的错误
    <李> <代码>router.delete('/:orderId', (req, res, next) =>{Order.remove ({_id: req.params.orderId},(呃,数据)=祝辞{如果(err) {* * res.status (500) . json (err); * *其他}{res.status (200) . json(数据);}* res.status (200) . json(数据);*})})李< /代码> < / >

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

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

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

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

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

 auth.annonymousOnly = function(req, res, next) {// add other task hereres.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 res.send(200))之前使用return来解决

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 = 422res.json(err)return // without this return the error can happen.}return res.json(data)})

在节点版本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为真,那么在第二个render中,你会得到这个错误

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

res.send(发送响应的);

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

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

我简单地添加了return关键字,比如:return res.redirect("/great");,它成功了!< / p >

在RND后自行查找错误:

1)我的错误代码:

# 0

2)我的成功密码

# 0

不同之处在于我使用了sendStatus ()而不是状态()

我的问题是,我有一个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 {. . .

把0放在1之前就成功了。

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

要解决这个问题,你必须启用Promises,所以你可以在代码中添加:mongoose.Promise = global.Promise,这样就可以使用native js promises

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

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

而且

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

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

在我的情况下,在循环中,我把res.render(),所以可能已经尝试调用多次。

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

< p >的过程。Env不会改变,因此它不能用于访问每个请求的环境变量,这些变量的值可能会根据每个请求而改变。因此,如果用户生成了一个应用程序进程,但不是作为处理请求的一部分,那么该应用程序进程将不会在操作系统级环境变量中存储每个请求的环境变量。所以,使用这段代码来存储进程env和你的程序成功运行
    const port = process.env.PORT || 2000;    
app.listen(port,()=>{console.log("Server running at port 2000");})

请在你的应用程序中搜索是否在res.send("your result")之前不设置状态;

我只是删除了:

res.sendStatus(200);

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

res.send("your result");

在我的情况下,这是反复出现的,当我没有让一个函数运行在mongodb模式的异步函数像technicianAuthSchema.methods.matchPasswords = function(password) { return await bcrypt.compare( password, this.password ); };我得到这个Logged error: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client 而不是technicianAuthSchema.methods.matchPasswords = async function(password) { return await bcrypt.compare( password, this.password ); };它是异步的,因为< >强this.password < / >强是来自这个函数运行的对象,我们正在从数据库中拉。

检查代码。对我来说,我在同一个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")之前

enter image description here

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

如果在一个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的新版本支持# 0布尔表达式。你可以用它来验证你是否已经发送了一个响应:

if (!res.headersSent) // if doesn't sent yetres.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。

// oldres.sendStatus(200);
// newres.status(200);

有时只是写作# 0还不够。几个小时后,我发现我们有时不得不返回return响应。这样的< / p >

# 0

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

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

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

检查是否使用了正确的表单方法。默认值是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);