【发布时间】: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.Validate、Authorizer.CheckPermission和TradeModule.Post? -
这种情况下的处理程序仅在出现错误时返回响应,否则如果这是您的意思,他们会调用 next(),但我想我知道您来自哪里跨度>
-
好吧,你得到了一个错误,所以你说应该调用
next,但你也调用了试图返回响应的res.status(error.HTTPCode).json(error.ToObject());。尝试删除res.status...,然后让错误处理程序处理响应。