import { Injectable, Injector } from '@angular/core'; import { Router } from '@angular/router'; import { HttpInterceptor, HttpRequest, HttpHandler, HttpErrorResponse, HttpSentEvent, HttpHeaderResponse, HttpProgressEvent, HttpResponse, HttpUserEvent, } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import { of } from 'rxjs/observable/of'; import { ErrorObservable } from 'rxjs/observable/ErrorObservable'; import { mergeMap, catchError } from 'rxjs/operators'; import { NzMessageService } from 'ng-zorro-antd'; import { _HttpClient } from '@delon/theme'; import { environment } from '@env/environment'; /** * 默认HTTP拦截器,其注册细节见 `app.module.ts` */ @Injectable() export class DefaultInterceptor implements HttpInterceptor { constructor(private injector: Injector) {} get msg(): NzMessageService { return this.injector.get(NzMessageService); } private goTo(url: string) { setTimeout(() => this.injector.get(Router).navigateByUrl(url)); } private handleData(event: HttpResponse | HttpErrorResponse): Observable { // 可能会因为 `throw` 导出无法执行 `_HttpClient` 的 `end()` 操作 this.injector.get(_HttpClient).end(); // 业务处理:一些通用操作 switch (event.status) { case 200: // 业务层级错误处理,以下假如响应体的 `status` 若不为 `0` 表示业务级异常 // 并显示 `error_message` 内容 // const body: any = event instanceof HttpResponse && event.body; // if (body && body.status !== 0) { // this.msg.error(body.error_message); // // 继续抛出错误中断后续所有 Pipe、subscribe 操作,因此: // // this.http.get('/').subscribe() 并不会触发 // return ErrorObservable.throw(event); // } break; case 401: // 未登录状态码 this.goTo('/passport/login'); break; case 403: case 404: case 500: this.goTo(`/${event.status}`); break; } return of(event); } intercept(req: HttpRequest, next: HttpHandler): Observable | HttpUserEvent> { // 统一加上服务端前缀 let url = req.url; if (!url.startsWith('https://') && !url.startsWith('http://')) { url = environment.SERVER_URL + url; } const newReq = req.clone({ url: url }); return next.handle(newReq).pipe( mergeMap((event: any) => { // 允许统一对请求错误处理,这是因为一个请求若是业务上错误的情况下其HTTP请求的状态是200的情况下需要 if (event instanceof HttpResponse && event.status === 200) return this.handleData(event); // 若一切都正常,则后续操作 return of(event); }), catchError((err: HttpErrorResponse) => this.handleData(err)) ); } }