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


724

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

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



2
Google向我提出了这个问题,但较新版本的ExpressJS具有res.headersSent布尔值,可用于检查是否可以安全设置/发送标头
朱利安·索罗

Answers:


1112

resExpress中的对象是Node.js的http.ServerResponse子类(请参阅http.js源)。允许您随意拨打电话res.setHeader(name, value),直到致电为止res.writeHead(statusCode)。之后writeHead,将标题放入其中,您只能调用res.write(data),最后res.end(data)

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

在您的情况下,您致电res.redirect(),这导致响应变为“完成”。然后,您的代码引发了错误(res.reqis null)。并且由于该错误发生在您的实际错误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. res.header(key[, val]) (仅限快递)
  7. res.charset = 'utf-8' (仅Express;仅影响Express特定的方法)
  8. res.contentType(type) (仅限快递)

响应必须在头部,并成为身体

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

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

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

响应可以是Head / Body,也可以是Finished

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

响应可以处于Head / Body,也可以保持其当前状态:

  1. res.addTrailers(headers)

响应必须在标题中,并已完成

  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]) (仅限快递)

13
是的,检查两次调用next()或其他cb。
托尼·古铁雷斯

3
快递链接似乎已失效
Korhan Ozturk

25
还要注意这个经典的错误:res.redirect()不会停止语句的执行...因此返回。否则,可能会执行其他代码,这些代码可能会不必要地导致著名的标头错误。感谢您的解释!
KLoozen '16

通常最好在回调的末尾使用return来避免这种情况
thethakuri

4
我在中间件取得了非常小的错误,我没有return之前next(),这得益于向我指出错误!
illcrx

113

我也有一段时间遇到这个错误。我想(希望)我把头缠住了,想在这里写一下以供参考。

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

问题是,如果在其中一个中间件项中写入响应主体或标头(看起来是/或某种原因),但没有调用,response.end()并且您next()在核心Server.prototype.handle方法完成后调用了它,这将引起注意那:

  1. 堆栈中没有其他物品,和/或
  2. 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的服务器感到困惑。


7
+1这是一个很好的解释,但是使用res.redirect()时会怎样呢?当中间件试图基于某种条件进行重定向时,我经常遇到此问题。按照您的“良好中间件”示例,中间件是否不应该重定向?
qodeninja

您知道由于您所说的有问题的中间件而有这个确切的问题,但是我需要返回响应但想在单独的控制器中作为链的一部分进行进一步处理的情况,如何解决这个错误?
智商。

57

此问答中的某些答案是错误的。接受的答案也不是很“实用”,因此我想发布一个答案,以更简单的方式解释事情。我的答案将涵盖我一次又一次看到的错误中的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()代码示例中,我们有一个异步函数()。如果没有错误(errfindOneAndUpdate()将被调用。由于此函数是异步的,因此res.json(doc1)将立即调用。假设中没有错误findOneAndUpdate()。将res.json(doc2)else随后将被调用。现在已发送两个响应,并且出现“无法设置标题”错误消息。

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


2
你是一个异步函数里面,且必须returnres.json
Genovo

我的问题是res.send在for循环中使用。
Maihan Nijat '18

1
这最终帮助我理解并解决了该问题,非常感谢:)
Pankaj Parkar '18

非常感谢您,节省了我的时间。
Mohammad Faisal

这绝对是最好的答案!
Juanma Menendez

53

我遇到了同样的问题,并意识到这是因为我在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();
};

43

很多人遇到此错误。这与异步处理混淆了。您的某些代码很可能在第一个刻度中设置了标头,然后在以后的刻度中运行了异步回调。在此之间,将发送响应头,但随后的其他头(例如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

3
哦 我想象连续30次重定向或类似的操作
Janac Meena

17

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

我的程序有一个验证请求并查询数据库的代码。验证是否存在错误之后,我用验证错误回调了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);

1
谢谢!原来这也是我的问题。只是做了一个ctrl + f,发现后面callback(...)没有一个return;,最终导致res.send(...)被调用两次。

15

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

例如:

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

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

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


这是我的确切问题:)
乔尔·巴尔默

6

有时,在尝试在res.endres.send之后调用next()函数时可能会遇到此错误,如果函数中在res.endres.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()从上述功能中删除,它将起作用。


6

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

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


4

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

if(condition A)
{ 

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

}

if (condition B){

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

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


3

在我的情况下,导致问题的原因是304响应(缓存)。

最简单的解决方案:

app.disable('etag');

如果您想要更多控制权,请在此处使用替代解决方案:

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


就我而言,也有304个回应。我正在使用纤维进行加工。无论如何,您的答案都会有很大帮助。谢谢
Dileep stanley 2014年

谁能解释删除etag标头的含义?
mattwilsn

2
ETag允许服务器不发送未更改的内容。将其关闭将禁用此功能。ETag Wikipedia条目(en.wikipedia.org/wiki/HTTP_ETag)有一个较长的说明。
变宽了

3

就我而言,这发生在React和postal.js上,这是因为我没有在componentWillUnmountReact组件的回调中退订通道。


2

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

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


1
您如何处理超时以避免这种情况?

2

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

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

2

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

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

2

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


1

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


您如何解决此问题?我对诺言有同样的问题。我无法避免嵌套它们...所以如何在return语句处停止执行?
萨拉巴


1

请检查您的代码是否针对单个请求返回多个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; }


谢谢您的启发,我也一样。如果条件允许,我也用其他方法解决了。
Amr AbdelRahman

1

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




1

我有猫鼬造成的同样问题。

修复必须启用的功能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;

但您需要先安装这些软件包。


1

在RND之后自行查找错误:

1)我的错误代码:

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

2)我的成功代码

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

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


0

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

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

0

如果您没有从上面得到帮助:傻瓜这个错误的原因是多次发送请求,因此让我们从某些情况中了解:-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()的`会引发错误

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

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



0

我的问题是我有一个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的把戏。



-1

如果发生此错误,我要做的就是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 
};
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.