我正在使用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);
我可以知道我的代码出了什么问题吗?
#1 楼
Express中的res
对象是Node.js http.ServerResponse
的子类(请阅读http.js源代码)。您可以随意拨打res.setHeader(name, value)
,直到您拨打res.writeHead(statusCode)
为止。在writeHead
之后,将烘焙标题,并且您只能调用res.write(data)
,最后只能调用res.end(data)
。错误“错误:发送标题后无法设置标题”。表示您已经处于“正文”或“完成”状态,但是某些函数试图设置标头或statusCode。当您看到此错误时,请尝试查找在某些正文已被写入之后尝试发送标头的任何内容。例如,查找意外调用两次的回调,或在发送正文后发生的任何错误。
在您的情况下,您调用了
res.redirect()
,这导致响应变为“完成”。然后,您的代码引发错误(res.req
是null
)。并且由于该错误发生在您的实际function(req, res, next)
中(而不是在回调中),因此Connect能够捕获该错误,然后尝试发送500错误页面。但是由于标头已经发送,Node.js的setHeader
引发了您看到的错误。Node.js / Express响应方法的完整列表以及何时调用它们:
Response必须位于Head和保留在头部中:
res.writeContinue()
res.statusCode = 404
res.setHeader(name, value)
res.getHeader(name)
res.removeHeader(name)
res.header(key[, val])
(仅表达)res.charset = 'utf-8'
(仅Express;仅影响Express特定的方法)res.contentType(type)
(仅Express)响应必须在Head并变为Body:
res.writeHead(statusCode, [reasonPhrase], [headers])
响应可以在任何一个Head / Body中,并保留在主体中:
res.write(chunk, encoding='utf8')
响应可以在任意一个Head / Body中正文并完成:
res.end([data], [encoding])
响应可以处于Head / Body中,也可以保持其当前状态:
res.addTrailers(headers)
响应必须在头部并完成:
return next([err])
(仅限连接/快速)中间件
function(req, res, next)
(仅用于连接/表达)中的任何异常res.send(body|status[, headers|status[, status]])
(仅用于表达表达)res.attachment(filename)
(仅用于表达表达)res.sendfile(path[, options[, callback]])
(仅用于表达表达) res.json(obj[, headers|status[, status]])
(仅表达)res.redirect(url[, status])
(仅表达)res.cookie(name, val[, options])
(仅表达)res.clearCookie(name[, options])
(表达)仅res.render(view[, options[, fn]])
(仅表达)res.partial(view[, options])
(仅表达)评论
是的,检查两次调用next()或其他cb。
–托尼·古铁雷斯(Tony Gutierrez)
15年5月6日在18:19
快递链接似乎已失效
–Korhan Ozturk
2015年12月3日在16:36
还要注意这个经典的错误:res.redirect()不会停止语句的执行...因此返回。否则,可能会执行其他代码,这些代码可能会不必要地导致著名的标头错误。感谢您的解释!
– KLoozen
16 Jan 23 '11:44
通常最好在回调的末尾使用return来避免这种情况
–thethakuri
16年6月1日在8:45
我在中间件中犯了一个非常小的错误,我没有在next()之前返回,谢谢,这使我指出了错误!
–illcrx
16 Dec 30 '20:32
#2 楼
我也有一段时间遇到这个错误。我想(希望)已经把它缠住了,想在这里写一下以供参考。当您添加使用
app.use
方法进行连接或表示(基于connect建立)的中间件时,您要在connect中向Server.prototype.stack
追加项目(至少与当前的npm install connect
相比,看起来与本文中的一个github完全不同)。服务器收到请求后,将遍历整个堆栈,并调用(request, response, next)
方法。问题是,如果中间件之一在其中写入响应主体或标头(看起来像/或出于某种原因),但没有调用response.end()
,而是调用next()
,然后在核心Server.prototype.handle
方法完成后,您会注意到:堆栈和/或
response.headerSent
是真实的。因此,它将引发错误。但是它引发的错误只是这个基本响应(来自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 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的服务器。评论
+1这是一个很好的解释,但是使用res.redirect()时会怎样呢?当中间件试图基于某种条件进行重定向时,我经常遇到此问题。按照您的“优质中间件”示例,中间件是否不应该重定向?
–qodeninja
2012年12月6日在22:45
您知道由于您所说的有问题的中间件而有这个确切的问题,但是我需要返回响应但想在单独的控制器中作为链的一部分进行进一步处理的情况,如何解决这个错误?
– iQ。
2014年10月30日14:03
#3 楼
此问答中的某些答案是错误的。接受的答案也不是很“实用”,因此我想发布一个答案,以更简单的方式解释事情。我的答案将涵盖我一次又一次看到的错误中的99%。出于错误背后的实际原因,请看一下可接受的答案。HTTP使用一个周期,每个请求需要一个响应。客户端发送请求(例如POST或GET)时,服务器应仅向其发送一个响应。
此错误消息:
错误:可以发送标头后,请不要设置标头。
通常在您为一个请求发送多个响应时发生。确保每个请求仅调用以下函数一次:
res.json()
res.send()
res.redirect()
res.render()
(以及还有一些很少使用的方法,请检查接受的答案)
调用这些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);
});
<异步函数是一个很大的缺点。以这个问题的函数为例: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()
中没有错误。然后将调用res.json(doc2)
中的else
。现在已发送了两个响应,并且出现“无法设置标头”错误消息。在这种情况下,解决方法是删除
res.json(doc1)
。要将两个文档发送回客户端,可以将其他文档中的res.json()
写为res.json({ article: doc1, user: doc2 })
。评论
您在异步函数中,必须返回res.json
–热那亚
18年7月1日在5:10
我的问题是使用res.send在for循环中。
– Maihan Nijat
18年9月7日在12:50
#4 楼
我遇到了同样的问题,并意识到这是因为我在没有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();
};
评论
如果返回,将无法进入next()。
–菊苣
8月21日19:22
@corysimmons我不明白你的意思。目的是如果调用了重定向,则不调用下一个。不希望在返回后再打电话。
–ergusto
8月29日1:45
#5 楼
很多人遇到此错误。这与异步处理混淆了。您的某些代码很可能在第一个刻度中设置了标头,然后在以后的刻度中运行了异步回调。在这之间,响应头被发送,但是随后的头(例如30X重定向)尝试添加额外的头,但是由于响应头已经被传输为时已晚。我不是确定到底是什么导致了您的错误,但是将所有回调作为潜在的研究领域。
一个简单的技巧可以简化您的代码。摆脱
app.configure()
,直接在您的顶级范围内直接调用app.use
。另请参阅everyauth模块,该模块可用于Facebook和十几个其他第三方身份验证提供程序。
评论
30X重定向是HTTP响应代码。 w3.org/Protocols/rfc2616/rfc2616-sec10.html代码300-399是重定向的不同变体,其中302和301通常用于将客户端发送到备用URL。当您在节点中执行response.redirect(...)时,将在响应中发送30X重定向标头。
– Peter Lyons
2011-12-23 21:23
哦我想象连续30次重定向
–贾纳克·梅纳(Janac Meena)
18年3月16日在20:54
#6 楼
我为解决这个问题而烦恼,但由于处理回调时出现了一个粗心的错误,所以发生了这种情况。未返回的回调导致将响应设置两次。!我的程序有一个验证请求并查询数据库的代码。验证是否存在错误后,我使用验证错误回调了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);
评论
谢谢!原来这也是我的问题。只是做了一个ctrl + f并发现了一个没有返回值的回调(...);之后它最终导致res.send(...)被调用两次。
–user993683
16年6月13日在16:22
#7 楼
发送响应后传递语句时,会出现这种错误。例如:
res.send("something response");
console.log("jhgfjhgsdhgfsdf");
console.log("sdgsdfhdgfdhgsdf");
res.send("sopmething response");
会导致错误正在看到,因为一旦发送了响应,将不会执行以下
res.send
。如果要执行任何操作,则应在发送响应之前执行此操作。
#8 楼
有时在尝试在res.end或res.send之后调用next()函数时可能会遇到此错误,如果函数中在res.end或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()
即可使用。#9 楼
如果使用回调函数,请在return
块之后使用err
。这是可能发生此错误的情况之一。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)
})
在节点版本
v10.16.0
上进行了测试并表达4.16.4
#10 楼
当您发送2个响应时,会发生此错误。例如:if(condition A)
{
res.render('Profile', {client:client_});
}
if (condition B){
res.render('Profile', {client:client_});
}
}
想象一下,如果由于某种原因条件A和B为真,那么在第二个
render
中,您将得到该错误#11 楼
在RND之后自行查找错误:1)我的错误代码:
return res.sendStatus(200).json({ data: result });
2)我的成功代码
return res.status(200).json({ data: result });
所不同的是,我使用sendStatus()而不是status()。
#12 楼
对于任何想解决此问题的人,其他解决方案都无济于事,就我而言,这体现在处理图像上传但不处理超时的路由上,因此,如果上载时间太长且超时,则触发回调时发送超时响应后,调用res.send()导致崩溃,因为标头已设置为解决超时问题。通过设置很短的超时时间并点击即可轻松重现这条路线的图像相当大,每次都崩溃了。
评论
您如何处理超时以避免这种情况?
–user5780947
19年2月1日在17:14
#13 楼
就我而言,当我没有从React组件的componentWillUnmount
回调中的某个频道退订时,React和postal.js就会发生这种情况。#14 楼
我只需添加返回关键字,例如:return res.redirect("/great");
和walla!#15 楼
在我的情况下,是导致问题的304响应(缓存)。最简单的解决方案:
app.disable('etag');
如果需要更多控制,请在此处使用替代解决方案:
http:// vlasenko .org / 2011/10/12 / expressconnect-static-set-last-modified-to-to-to-to-to-to-void-304-not-modified /
评论
就我而言,也有304个回应。我正在使用Fibers进行处理。无论如何,您的答案都会有很大帮助。谢谢
– Dileep stanley
2014年7月26日16:00
谁能解释删除etag标头的含义?
– mattwilsn
16年5月23日在16:17
ETag允许服务器不发送未更改的内容。将其关闭将禁用此功能。 ETag Wikipedia条目(en.wikipedia.org/wiki/HTTP_ETag)有较长的说明。
–丰富
16年5月24日在18:25
#16 楼
只是靠这个。您可以通过以下功能传递响应: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();
});
#17 楼
添加此中间件,它将起作用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();
});
#18 楼
当响应传递到客户端时,您再次尝试提供响应时,就会发生这种情况。您必须检入代码,确认您正在某个地方再次将响应返回给客户端,这会导致此错误。要返回时,检查并返回一次响应。#19 楼
还有其他原因导致此错误,就是您没有在res.send,res.json等前面添加return关键字的时候。#20 楼
这很可能是节点的事情,在99%的时间内,它是一个双重回调,导致您响应两次,或者next()两次,等等,该死。它解决了我的问题是在循环内使用next()。从循环中删除next()或停止多次调用。评论
我有同样的错误,它是由于在同一中间件函数中调用了两个函数,而每个函数都调用了next()而引起的。我通过创建第二个中间件函数并将这些函数之一移入其中来解决了该错误,因此每个中间件函数中只有一个next()调用。这是解决问题的提交:github.com/DataHighway-DHX/faucet/commit/…
–卢克·肖恩(Luke Schoen)
6月28日14:55
#21 楼
我遇到了由猫鼬引起的相同问题。要修复必须启用
Promises
,因此可以在代码中添加:mongoose.Promise = global.Promise
,从而可以使用native js promises
。此解决方案的其他替代方法是:
var mongoose = require('mongoose');
// set Promise provider to bluebird
mongoose.Promise = require('bluebird');
和
// q
mongoose.Promise = require('q').Promise;
,但是您需要先安装这些软件包。
#22 楼
我嵌套诺言时遇到了这个问题。一个内部的Promise将向服务器返回200,但是外部的Promise的catch语句将返回500。一旦我解决了这个问题,问题就消失了。评论
您如何解决此问题?我对诺言有同样的问题。我无法避免嵌套它们...那么如何在return语句处停止执行?
–索伯
3月23日9:28
#23 楼
从nuxt来到这里,问题出在组件的asyncData
方法中,我忘记了return
的诺言,那是在那里获取数据并设置标头。#24 楼
请检查您的代码是否针对单个请求返回多个res.send()语句。就像我遇到这个问题时一样。...我在我的reify节点应用程序中就是这个问题。错误是
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;
}
#25 楼
当我尝试在循环函数中发送响应时,出现了类似的错误。简单的解决方案是将res.send('send response');
移出循环,因为您只能发送响应标头一次。
https://www.tutorialspoint.com/nodejs/nodejs_response_object.htm
#26 楼
在Typescript中,我的问题是收到消息后我没有关闭websocket连接。WebSocket.on("message", (data) => {
receivedMessage = true;
doSomething(data);
localSocket.close(); //This close the connection, allowing
});
#27 楼
如果您没有从上面得到帮助:对于菜鸟此错误背后的原因是多次发送请求,因此让我们从某些情况中了解:-
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);*
})
})
这里的响应是发送两次,请检查您是否已经发送了响应
#28 楼
就我而言,它是由于多个回调而发生的。我在代码期间多次调用了next()
方法#29 楼
我的问题是我运行了一个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
进行招。#30 楼
就我而言,在循环中,我放入了res.render()
,因此可能已尝试多次调用。
评论
视觉媒体的简单答案:github.com/visionmedia/express/issues/634Google向我提出了这个问题,但较新版本的ExpressJS具有res.headersSent布尔值,可用于检查设置/发送标头是否安全