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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7042340/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 00:24:22  来源:igfitidea点击:

Error: Can't set headers after they are sent to the client

javascriptnode.jsexpress

提问by DjangoRocks

I'm fairly new to Node.js and I am having some issues.

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

I am using Node.js 4.10 and Express 2.4.3.

我使用的是 Node.js 4.10 和 Express 2.4.3。

When I try to access http://127.0.0.1:8888/auth/facebook, i'll be redirected to http://127.0.0.1:8888/auth/facebook_callback.

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

I then received the following error:

然后我收到以下错误:

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)

The following is my code:

以下是我的代码:

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

May I know what is wrong with my code?

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

回答by yonran

The resobject in Express is a subclass of Node.js's http.ServerResponse(read the http.js source). You are allowed to call res.setHeader(name, value)as often as you want until you call res.writeHead(statusCode). After writeHead, the headers are baked in and you can only call res.write(data), and finally res.end(data).

resExpress 中的对象是Node.js 的http.ServerResponse子类(阅读 http.js 源代码)。您res.setHeader(name, value)可以随心所欲地拨打电话,直到您拨打res.writeHead(statusCode)。之后writeHead,标题被烘烤,您只能调用res.write(data),最后res.end(data)

The error "Error: Can't set headers after they are sent." means that you're already in the Body or Finished state, but some function tried to set a header or statusCode. When you see this error, try to look for anything that tries to send a header after some of the body has already been written. For example, look for callbacks that are accidentally called twice, or any error that happens after the body is sent.

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

In your case, you called res.redirect(), which caused the response to become Finished. Then your code threw an error (res.reqis null). and since the error happened within your actual function(req, res, next)(not within a callback), Connect was able to catch it and then tried to send a 500 error page. But since the headers were already sent, Node.js's setHeaderthrew the error that you saw.

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

Comprehensive list of Node.js/Express response methods and when they must be called:

Node.js/Express 响应方法的完整列表以及必须调用它们的时间:

Response must be in Headand remains in Head:

响应必须在Head 中并保留在Head 中

  1. res.writeContinue()
  2. res.statusCode = 404
  3. res.setHeader(name, value)
  4. res.getHeader(name)
  5. res.removeHeader(name)
  6. res.header(key[, val])(Express only)
  7. res.charset = 'utf-8'(Express only; only affects Express-specific methods)
  8. res.contentType(type)(Express only)
  1. res.writeContinue()
  2. res.statusCode = 404
  3. res.setHeader(name, value)
  4. res.getHeader(name)
  5. res.removeHeader(name)
  6. res.header(key[, val])(仅限快递)
  7. res.charset = 'utf-8'(仅限 Express;仅影响 Express 特定的方法)
  8. res.contentType(type)(仅限快递)

Response must be in Headand becomes Body:

响应必须在Head 中并变成Body

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

Response can be in either Head/Bodyand remains in Body:

响应可以在Head/Body 中并保留在Body 中

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

Response can be in either Head/Bodyand becomes Finished:

响应可以在Head/Body 中,并变为Finished

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

Response can be in either Head/Bodyand remains in its current state:

响应可以在Head/Body 中并保持其当前状态:

  1. res.addTrailers(headers)
  1. res.addTrailers(headers)

Response must be in Headand becomes Finished:

响应必须在Head 中并变为Finished

  1. return next([err])(Connect/Express only)
  2. Any exceptions within middleware function(req, res, next)(Connect/Express only)
  3. res.send(body|status[, headers|status[, status]])(Express only)
  4. res.attachment(filename)(Express only)
  5. res.sendfile(path[, options[, callback]])(Express only)
  6. res.json(obj[, headers|status[, status]])(Express only)
  7. res.redirect(url[, status])(Express only)
  8. res.cookie(name, val[, options])(Express only)
  9. res.clearCookie(name[, options])(Express only)
  10. res.render(view[, options[, fn]])(Express only)
  11. res.partial(view[, options])(Express only)
  1. return next([err])(仅限连接/快递)
  2. 中间件中的任何异常function(req, res, next)(仅限 Connect/Express)
  3. res.send(body|status[, headers|status[, status]])(仅限快递)
  4. res.attachment(filename)(仅限快递)
  5. res.sendfile(path[, options[, callback]])(仅限快递)
  6. res.json(obj[, headers|status[, status]])(仅限快递)
  7. res.redirect(url[, status])(仅限快递)
  8. res.cookie(name, val[, options])(仅限快递)
  9. res.clearCookie(name[, options])(仅限快递)
  10. res.render(view[, options[, fn]])(仅限快递)
  11. res.partial(view[, options])(仅限快递)

回答by Lance Pollard

I ran into this error as well for a while. I think (hope) I've wrapped my head around it, wanted to write it here for reference.

我也遇到了这个错误一段时间。我想(希望)我已经把我的头围绕在它上面,想把它写在这里以供参考。

When you add middleware to connector express(which is built on connect) using the app.usemethod, you're appending items to Server.prototype.stackin connect (At least with the current npm install connect, which looks quite different from the one github as of this post). When the server gets a request, it iterates over the stack, calling the (request, response, next)method.

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

The problem is, if in one of the middleware items writes to the response body or headers (it looks like it's either/or for some reason), but doesn't call response.end()and you call next()then as the core Server.prototype.handlemethod completes, it's going to notice that:

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

  1. there are no more items in the stack, and/or
  2. that response.headerSentis true.
  1. 堆栈中没有更多项目,和/或
  2. response.headerSent是真实的。

So, it throws an error. But the error it throws is just this basic response (from the connect http.jssource code:

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

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

Right there, it's calling res.setHeader('Content-Type', 'text/plain');, which you are likely to have set in your rendermethod, without calling response.end(), something like:

就在那里,它正在调用res.setHeader('Content-Type', 'text/plain');,您可能已经在render方法中设置了它,而没有调用 response.end(),例如:

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

The way everything needs to be structured is like this:

一切都需要结构化的方式是这样的:

Good Middleware

好的中间件

// 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);

Problematic Middleware

有问题的中间件

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

The problematic middleware sets the response header without calling response.end()and calls next(), which confuses connect's server.

有问题的中间件在没有调用response.end()和调用的情况下设置响应头next(),这会混淆连接的服务器。

回答by Mika Sundland

Some of the answers in this Q&A are wrong. The accepted answer is also not very "practical", so I want to post an answer that explains things in simpler terms. My answer will cover 99% of the errors I see posted over and over again. For the actual reasons behind the error take a look at the accepted answer.

本问答中的一些答案是错误的。接受的答案也不是很“实用”,所以我想发布一个用更简单的术语解释事物的答案。我的回答将涵盖我一遍又一遍地看到的 99% 的错误。对于错误背后的实际原因,请查看已接受的答案。



HTTP uses a cycle that requires one response per request. When the client sends a request (e.g. POST or GET) the server should only send one response back to it.

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

This error message:

此错误消息:

Error: Can't set headers after they are sent.

错误:发送后无法设置标头。

usually happens when you send several responses for one request. Make sure the following functions are called only once per request:

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

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

(and a few more that are rarely used, check the accepted answer)

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

The route callback will not return when these res functions are called. It will continue running until it hits the end of the function or a return statement. If you want to return when sending a response you can do it like so: return res.send().

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



Take for instance this code:

以这段代码为例:

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

When a POST request is sent to /api/route1it will run every line in the callback. A Can't set headers after they are senterror message will be thrown because res.json()is called twice, meaning two responses are sent.

当 POST 请求发送到/api/route1 时,它将运行回调中的每一行。A Can't set headers after they're sent错误信息将被抛出,因为res.json()被调用了两次,意味着发送了两个响应。

Only one response can be sent per request!

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



The error in the code sample above was obvious. A more typical problem is when you have several branches:

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

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

This route with attached callback finds a company in a database. When doing a query for a company that doesn't exist we will get inside the else ifbranch and send a 404 response. After that, we will continue on to the next statement which also sends a response. Now we have sent two responses and the error message will occur. We can fix this code by making sure we only send one response:

这条带有回调的路由在数据库中查找公司。当对不存在的公司进行查询时,我们将进入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);
  }
});

or by returning when the response is sent:

或者在发送响应时返回:

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


A big sinner is asynchronous functions. Take the function from thisquestion, for example:

一个大罪人是异步函数。从这个问题中获取函数,例如:

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

Here we have an asynchronous function (findOneAndUpdate()) in the code sample. If there are no errors (err) findOneAndUpdate()will be called. Because this function is asynchronous the res.json(doc1)will be called immediately. Assume there are no errors in findOneAndUpdate(). The res.json(doc2)in the elsewill then be called. Two responses have now been sent and the Can't set headerserror message occurs.

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

The fix, in this case, would be to remove the res.json(doc1). To send both docs back to the client the res.json()in the else could be written as res.json({ article: doc1, user: doc2 }).

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

回答by ergusto

I had this same issue and realised it was because I was calling res.redirectwithout a returnstatement, so the nextfunction was also being called immediately afterwards:

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

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

Which should have been:

应该是:

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

回答by Peter Lyons

Lots of people hit this error. It's a confusing this with async processing. Most likely some of your code is setting headers in the first tick and then you are running an async callback in a future tick. In between, the response header gets sent, but then further headers (like a 30X redirect) try to add extra headers, but it's too late since the response header has already been transmitted.

很多人都遇到了这个错误。这与异步处理令人困惑。很可能您的某些代码在第一个滴答中设置标头,然后您在未来的滴答中运行异步回调。在这中间,响应标头被发送,但随后的更多标头(如 30X 重定向)尝试添加额外的标头,但为时已晚,因为响应标头已经被传输。

I'm not sure exactly what's causing your error, but look at any callbacks as potential areas to investigate.

我不确定究竟是什么导致了您的错误,但请将任何回调视为需要调查的潜在领域。

One easy tip to simplify your code. Get rid of app.configure()and just call app.usedirectly in your top level scope.

一个简化代码的简单技巧。摆脱app.configure()app.use直接在您的顶级范围内调用。

See also the everyauthmodule, which does Facebook and a dozen or so other 3rd party authentication providers.

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

回答by randomness

I boiled my head over this issue and it has happened due to a careless mistake on handling the callbacks. non returned callbacks cause the response to be set twice.!

我对这个问题焦头烂额,这是由于处理回调时的粗心错误而发生的。未返回的回调会导致响应设置两次。!

My program had a code which validate request and query the DB. after validating if error is there, I was calling back the index.js with the validation errors . And if validation passes it goes ahead and hit the db with success/failure.

我的程序有一个验证请求和查询数据库的代码。在验证是否存在错误后,我正在回调带有验证错误的 index.js。如果验证通过,它会继续并成功/失败击中数据库。

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

What was happening is : Incase validation fails the callback get called and response get set. But not returned. So it still continues the method goes to db and hit success/failure . It calls the same callback again causing the response to be set twice now.

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

So solution is simple, you need to 'return' the callback so that the method don't continue executing, once the error has occurred and hence set the response object once

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

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

回答by Trojan

This type of error you will get when you pass statements after sending a response.

发送响应后传递语句时会出现这种类型的错误。

For example:

例如:

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

Will result in the error you are seeing, because once the response has been sent, the following res.sendwill not be executed.

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

If you want do anything, you should do it before sending the response.

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

回答by Surendra Parchuru

Sometimes you may get this error when you try to call next() function after res.endor res.send, try to delete if you have next() after res.send or res.end in your function. Note: here next() means after responding to the client with your response(i.e res.send or res.end) you are still trying to execute some code to respond again so it is not legal.

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

Example :

例子 :

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

remove next()from above function and it will work.

next()从上面的功能中删除,它将起作用。

回答by Krishnadas PC

If you are using callback functions use returnafter the errblock. This is one of the scenarios in which this error can happen.

如果您使用回调函数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)
  })

Tested on Node version v10.16.0and express 4.16.4

在 Node 版本v10.16.0和 express上测试4.16.4

回答by Badr Bellaj

This error happens when you send 2 responses. For example :

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

if(condition A)
{ 

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

}

if (condition B){

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

Imagine if for some reason condition A and B are true so in the second renderyou'll get that error

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