我对Angular(8)并不陌生,但是一直在构建前端SPA,该SPA使用HttpClient模块对Node Express后端API进行http调用。在API响应中,我可以使用以下示例作为基本示例来设置Http响应状态以及其他JSON对象:
router.delete('/api/admin/roles', auth, (req, res) => {
queries.deleteRole(req.query.roleid, (err,result) => {
if (err) {
if (err.number == 547) {
return res.status(409).json({
message: 'Users exist with this role. Cannot cascade delete.'
})
}
return res.status(500).send()
}
return res.send(result)
})
})
当我在开发环境中运行上述命令时,我可以成功拦截HttpErrorResponse并使用message属性访问err.error对象。我的拦截器看起来像这样:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
this.toastService.show(new Toast('Your session has expired and you have been logged out. Please log back in.', 'Session expired', {'delay': 5000, 'classname': 'bg-info text-light'}))
this.authService.logOut();
} else if (err.status === 409) {
console.log(err)
let errText = err.error.message || 'Record has been updated by another user. Please refresh page and retry.'
this.toastService.show(new Toast(errText
, 'Update conflict', {'delay': 5000, 'classname': 'bg-danger text-light'}))
} else if (err.status == 403) {
this.toastService.show(new Toast('You do not have the appropriate permissions to perform this action. Please contact your line manager to request access.'
, 'Not authorized', {'delay': 5000, 'classname': 'bg-danger text-light'}))
}
}
return next.handle(req)
})
)
}
这一切在开发中都很好。但是,当我运行ng build --prod
并将应用程序部署到IIS服务器(使用iisnode),并创建相同的条件以从API接收HttpError时,响应错误属性不再包含我的自定义对象,而是恢复为“该页面未显示,因为发生了冲突。”,我猜这是响应409响应的一些标准字符串?
我看不到为什么在我的Angular代码或Node中,这取决于环境而表现不同,所以我假设这与ng build --prod
命令有关,或者与iisnode部署有关。 Google并没有提供帮助,事实上,在我遇到的每个留言板或教程中,建议的解决方案似乎都与我的工作大致相符,没有迹象表明部署到生产环境或任何人提到的内容可能有所不同否则他们会遇到相同的问题。
所以,我是否缺少明显的东西?任何帮助,将不胜感激。
好吧,我最终弄清楚了这一点,一个包含“ iisnode”一词的快速Google立即提供了解决方案。我不确定我以前怎么没想到这一点。
无论如何,对于任何为此苦苦挣扎的人,这是我遵循的解决方案的链接:https://github.com/tjanczuk/iisnode/issues/295
基本上,您需要在iisnode上的web.config文件中添加两件事:
<configuration>
<system.web>
<customErrors mode="off" /> <-- this one here
</system.web>
<system.webServer>
<httpErrors existingResponse="PassThrough" /> <-- and this one too
...
该线程实际上说要使用<httpErrors existingResponse="passthrough" />
,但我发现使用“ PassThrough”(使用大写字母)可以在原始小写字母值不起作用的情况下工作。