在使用HttpClient
的Angular服务中,我创建了一个从POST
返回原始HTTP响应的方法:
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
//observe: 'response'
}),
observe: 'response' as 'body'
};
forgotLogin(requestData: PUMRequestData): Observable<HttpResponse<string>> {
return this.http.post<HttpResponse<string>>("http://...", requestData, this.httpOptions);
然后在我的组件中,我只查看原始 http 响应的状态和正文。
this.api.forgotLogin(pumRequestData).subscribe(response => {
this.hStatus = response.status;
this.hBody = response.body;
});
问题是,如果响应状态不在200
系列中,则HttpClient
抛出错误。在我的用例中,我只想获取请求状态和正文,而不管状态是什么,并且我想根据组件中的状态而不是服务中的错误处理程序来决定要执行的操作。我一直在尝试找出一些棘手的方法,在服务中创建错误处理程序,该处理程序仅返回(可观察(HTTP
响应,但一直无法 - 甚至不确定这是否是正确的方法。
那么,当状态不是 200 系列时,如何将原始 http 响应返回到我的组件?
这对我有用,因为 HttpClient 无法检索纯文本。
That's right.
It works when there is no generic code applied to it.
it will work for:
http.get(url, {responseType: 'text'}
好吧,我屈服了,并按照建议使用错误处理程序解决了问题(感谢克里斯托弗(。我想要的是一个 http 客户端,无论状态如何,它都会将 http 响应传回给我,并且只有在没有返回响应时才抛出错误(例如不存在的域(。Angular HttpClient不会这样做。可能会有另一个http客户端库,但生命太短了。
我只需要 HTTP 状态和响应中的正文,所以我创建了此错误处理程序:
private handleError(error: HttpErrorResponse) {
if (error.status == 0)
return of({ status: 600, body: "Unexpected error. If this problem persists, please contact ..." })
else
return of({ status: error.status, body: error.error });
}
然后我的 API 调用方法如下所示:
changePassword(requestData: PUMRequestData): Observable<HttpResponse<string>> {
return this.http.put<any>("http:// ... /API/ChangePassword", requestData, this.httpOptions)
.pipe(catchError(err => this.handleError(err)));
}
现在,无论订阅者从成功的 HTTP 状态 200 调用还是从错误处理程序获取响应,它都将包含"状态"和"正文"。请注意,如果没有 HTTP 响应,则我设置了一个虚构的 HTTP 状态 600,在这种情况下,我必须提供正文中缺少的错误消息。此外,我还必须将 put 的数据类型从 HttpResponse 字符串更改为 any。
订阅HTTP
响应时,可以添加错误处理程序。HttpErrorResponse
对象包括继承自HttpResponseBase
的HttpHeaders
、status
和statusText
。
body
位于酒店HttpErrorResponse.error
。
HttpResponseBase
HttpErrorResponse
上可用的属性
- 标头:HttpHeaders - 所有响应标头。
- 状态:数字 - 响应状态代码。
- 状态文本:字符串 - 响应状态代码的文本说明。(不要依赖这个(
- url: string | null - 检索到的资源的 URL,如果不可用,则
null
。- 确定:布尔值 - 状态代码是否在 2xx 范围内。
例
this.api.forgotLogin(pumRequestData).subscribe(
response => {
this.hStatus = response.status;
this.hBody = response.body;
},
(error: HttpErrorResponse) => {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
}
);
错误处理程序也可以放在RXJSpipe
中,以便在订阅HTTP
请求之前嵌入它。
this.http.get<Object>(full_url, options).pipe(catchError((error: HttpErrorResponse) => {
// Process error here, such as logging.
...
return throwError(error)
}))
请参阅 AngularHttpClient
文档:错误处理