我正在开发一个Angular 2应用程序,需要一些关于如何干净地处理身份验证错误的指导。
我的最终目标是能够集中处理每个Http
请求的身份验证错误(特别是401和403)。
我发现this这个问题对于让我开始非常有帮助,但是我仍然坚持为我的自定义Http
实现返回的每个observable注册错误处理程序的正确方法。
以下是我目前正在使用的示例:
import { Injectable } from 'angular2/core';
import { Http, ConnectionBackend, Request, RequestOptions, RequestOptionsArgs, Response } from 'angular2/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class ClauthHttp extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
get(url: string, options ? : RequestOptionsArgs): Observable < Response > {
var response = super.get(url, options);
return this._handleSecurityResponse(response);
}
/*
Other overrides omitted for brevity...
*/
private _handleSecurityResponse(response: Observable < Response > ): Observable < Response > {
response.subscribe(null, (error: Response) => {
// Do some nifty error handling here.
});
return response;
}
}
上述解决方案“有效”,但每次HTTP请求都会发生两次。那不好。
有关如何正确执行此操作的任何指导?
(更新)工作代码
根据接受的答案中的信息,这个类在其正常运作的形式中是什么样的。
import {Injectable} from 'angular2/core';
import {Http, ConnectionBackend, Request, RequestOptions, RequestOptionsArgs, Response} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/share';
@Injectable()
export class ClauthHttp extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
}
get(url: string, options ? : RequestOptionsArgs): Observable < Response > {
var response = super.get(url, options);
return this._handleSecurityResponse(response);
}
/*
Other overrides omitted for brevity...
*/
private _handleSecurityResponse(response: Observable < Response > ): Observable < Response > {
var sharable = response.share();
sharable.subscribe(null, (error: Response) => {
// Do some nifty error handling here.
});
return sharable;
}
}
答案 0 :(得分:30)
这可能是由于您的Observable<Response>
是一个冷可观察的事实,即它为每个新用户'重新启动'。有关热与冷可观测量的解释,请查看Hot and Cold observables : are there 'hot' and 'cold' operators?。所以在这里你可能为结果处理程序订阅一次,为错误处理程序订阅另一次。
您应该可以通过“共享”您的observable
来解决订阅副作用即。替换
var response = super.get(url, options);
使用
var response = super.get(url, options).share();`