【问题标题】:Express.js - On second POST request: Can't set headers after they are sentExpress.js - 在第二个 POST 请求中:发送后无法设置标头
【发布时间】:2018-04-17 23:31:33
【问题描述】:

我在任何路由上向我的服务器发送一个 POST 请求。它将数据正确地存储在数据库中并返回没有错误的响应。

但是,如果我向同一路由发送另一个 POST 请求,使用正确且不同的 POST 信息,它将起作用,数据将存储在数据库中并且返回正确,但会触发异常:

EntityAlreadyExistsException, mongoose _id: 5ad5e661f2b3935b5b485890 already exists

然后是:

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

似乎即使响应已在第一个 POST 请求上成功发送回客户端,数据仍以某种方式保留在 API 中。

这是响应代码:

public static Respond(res: any, errorKey: string, data: any) {
     if (errorKey && errorKey.length != 0) {
         let error = new Error(errorKey);
         res.status(error.HTTPCode).json(error.ToObject());
     } else {
         res.status(200).json({ data: data });
     }
 }

如果第三次发送POST请求报错如下:

Error: Can't set headers after they are sent.
EntityAlreadyExistsException mongoose _id: 5ad5e661f2b3935b5b485890 already exists
Error: Can't set headers after they are sent.
EntityAlreadyExistsException mongoose _id: 5ad5e661f2b3935b5b485890 already exists
Success

在发送第三个 POST 请求时,上述内容将重复 3 次。 奇怪的是,除了控制台中的这些消息外,应用程序工作正常(正确存储数据并发送正确的响应)。 POST 请求通过 Postman 发送。

这里有一个类似的问题:Can't set headers after they are sent. on second call to REST API using Node and express

但是,这种解决方案在这种情况下不起作用。

路线文件:

      public static Start(app: any, config: any) {

      /* Open Routes */

    UserRoutes.StartOpenRoutes(Routes.router, config);

      /* End Of Open Routes */

    Routes.router.use((req, res, next) => { Authenticator.Verify(req, res, next, config); });

      /* Closed Routes */
    app.use("/", Routes.router);

    ContainerRoutes.StartClosedRoutes(Routes.router, config);

    PredictionRoutes.StartClosedRoutes(Routes.router, config);

    TradeRoutes.StartClosedRoutes(Routes.router, config);

    UserRoutes.StartClosedRoutes(Routes.router, config);

    app.use((req: any, res: any) => {
        Response.Respond(res, "undefined_route", null);
    });
  }

这里是贸易路线(TradeRoutes):

public static StartClosedRoutes(router: express.Router, config: any) {
    router.post('/trades', (req, res, next) => { Validator.Validate(req, res, next, 'POST /trades'); }
    , (req, res, next) => { Authorizer.CheckPermission(req, res, next, Actions.ADD_TRADE); }
    , (req, res, next) => { TradeModule.Post(req, res, next, config); });

    router.put('/trades/:id', (req, res, next) => { Validator.Validate(req, res, next, 'PUT /trades'); }
        , (req, res, next) => { Authorizer.CheckPermission(req, res, next, Actions.UPDATE_TRADE); }
        , (req, res, next) => { TradeModule.Put(req, res, next, config); });

    router.get('/trades/:id', (req, res, next) => { Authorizer.CheckPermission(req, res, next, Actions.GET_TRADE); }
        , (req, res, next) => { TradeModule.Get(req, res, next, config); });

    router.get('/trades', (req, res, next) => { Authorizer.CheckPermission(req, res, next, Actions.GET_TRADE); }, (req, res, next) => { TradeModule.Index(req, res, next, config); });

    router.delete('/trades/:id', (req, res, next) => { Authorizer.CheckPermission(req, res, next, Actions.DELETE_TRADE); }
        , (req, res, next) => { TradeModule.Delete(req, res, next, config); });
}

【问题讨论】:

  • 可能有助于查看更多代码。你如何处理http请求?我们可以看看你的路线吗?
  • 不用担心,添加它们
  • 我不确定您使用的是什么框架,但我的猜测是您正在传递多个处理程序来处理每个请求。对于您的/trades 路由,是否所有处理程序都被调用并试图返回响应?即Validator.ValidateAuthorizer.CheckPermissionTradeModule.Post?
  • 这种情况下的处理程序仅在出现错误时返回响应,否则如果这是您的意思,他们会调用 next(),但我想我知道您来自哪里跨度>
  • 好吧,你得到了一个错误,所以你说应该调用next,但你也调用了试图返回响应的res.status(error.HTTPCode).json(error.ToObject());。尝试删除res.status...,然后让错误处理程序处理响应。

标签: node.js express mongoose


【解决方案1】:

这个问题是由于没有清除猫鼬collectionChange boolean引起的。

每当更新/删除 mongo 数据库中的集合时,名为 tradeChange 的集合的内部属性将设置为 true,因此当调用内部方法 SubmitChanges 时,它将检查是否有任何集合需要 CRUD 操作。

在不重置值的情况下,mongoose 值会传播到下一次调用,依此类推。

【讨论】:

    猜你喜欢
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    相关资源
    最近更新 更多