我正在使用RC6,而我正试图弄清楚如何在整个应用程序中捕获HTTP错误 - 特别是auth错误。
有很多帖子描述了如何使用自定义类扩展Http
类,但我不确定如何完全注册新类,因为语法随着最近的更改而出现ngModule更改。
这是班级(添加了所有相关的导入):
@Injectable()
export class InterceptedHttp extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
super( backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
console.log('request...');
return super.request(url, options);
}
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
console.log('get...');
return super.get(url,options);
}
}
我以为我可以在providers
的{{1}}部分执行以下操作:
@ngModule
但是这只会让我失去一些模块错误:
imports: [ HttpModule, ... ],
providers: [
...
InterceptedHttp,
{provide: Http, useClass: InterceptedHttp },
ConnectionBackend
],
删除添加的行,一切正常。
那么,如何注册自定义Http类?
答案 0 :(得分:3)
我对此的看法不同。我创建了一个HTTPService
类,它与内置的Http
进行交互,而不是扩展Http
。
@Injectable()
export class HttpService{
constructor(private http:Http){}
/** Wrapper for Http.get() that intercepts requests and responses */
get(url:string, options?:RequestOptions):Observable<any>{
//pre-screen the request (eg: to add authorization token)
options = this.screenRequest(options);
return this.http.get(url,options)
.map(res => res.json()) //my back-end return a JSON. Unwrap it
.do(res => this.screenResponse(res)) // intercept response
.catch(res => this.handleError(res));// server returned error status
}
/** similar to the above; a wrapper for Http.post() */
post(url:string, body:string ,options?:RequestOptions):Observable<any>{}
/** edits options before the request is made. Adds auth token to headers.*/
screenOptions(options?:RequestOptions):RequestOptions{}
/** Called with server's response. Saves auth token from the server */
screenResponse(jsonResponse:any){}
/** Called when server returns a 400-500 response code */
handleError(response:Response){}
}
所以我的代码永远不会直接调用Angular&#39; Http
。相反,我打电话给HttpService.get()
。
答案 1 :(得分:2)
我采用了不同的方法并扩展了XHRBackend
,到目前为止它已经处理了我的所有需求。
export class CoreXHRBackend extends XHRBackend {
constructor(xhr:BrowserXhr, opts:ResponseOptions, strat:XSRFStrategy, public alerts:Alerts) {
super(xhr, opts, strat);
}
createConnection(request:Request) {
let xhr = super.createConnection(request);
/**
* Global error handler for http requests
*/
xhr.response = xhr.response.catch((error:Response) => {
if (error.status === 401 && window.location.pathname !== '/') {
this.alerts.clear().flash('You are not authorized to access that page', 'danger');
window.location.href = '/';
}
if (error.status === 404) {
this.alerts.clear().error('Sorry, we couldn\'t find that...');
}
// Validation errors or other list of errors
if (error.status === 422) {
var messages = error.json();
Object.keys(messages).map(k => this.alerts.error(messages[k]));
}
if (error.status === 500) {
this.alerts.clear().error('Sorry Something Went Wrong, Try Again Later!');
}
return Observable.throw(error);
});
return xhr;
}
}
我还需要注入我的自定义警报服务,构造函数不能注射,所以我在我的模块中处理了这个...
export class CoreModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: CoreModule,
providers: [
Alerts,
{
provide: XHRBackend,
useFactory: (xhr, opts, strat, alerts) => {
return new CoreXHRBackend(xhr, opts, strat, alerts);
},
deps: [ BrowserXhr, ResponseOptions, XSRFStrategy, Alerts ],
}
],
};
}
}