浅记一下angular的自定义http拦截器

153 阅读1分钟

1.在app.module下注入拦截器

@NgModule({
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true}
  ],
})

2.拦截器的详细代码如下

import { Injectable, Injector } from '@angular/core';
import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpErrorResponse,
  HttpSentEvent,
  HttpHeaderResponse,
  HttpProgressEvent,
  HttpResponse,
  HttpUserEvent,
} from '@angular/common/http';
import { Observable, of, throwError } from 'rxjs';
import { mergeMap, catchError } from 'rxjs/operators';

/**
 * 默认HTTP拦截器,其注册细节见 `app.module.ts`
 */
@Injectable()
export class DefaultInterceptor implements HttpInterceptor {

  constructor(
    private injector: Injector,
    private msg: NzMessageService) {}

  public intercept(
    req: HttpRequest<any>,
    next: HttpHandler,
  ): Observable<| HttpSentEvent
    | HttpHeaderResponse
    | HttpProgressEvent
    | HttpResponse<any>
    | HttpUserEvent<any>> {
    // 统一加上服务端前缀
    const url = req.url;
    const newReq = req.clone({
      url,
      setHeaders: {
          // 这里可以加一些token啥的放在请求头
      },
    });
    return next.handle(newReq)
      .pipe(
        mergeMap((event: any) => {
          // 允许统一对请求错误处理,这是因为一个请求若是业务上错误的情况下其HTTP请求的状态是0的情况下需要
          const resBody = event.body;
          const stateCode = resBody && resBody.code;
          if (event instanceof HttpResponse &&
            typeof(stateCode) === 'number') {
            if (stateCode === 0) {
              return this.handleData(event);
            } else {
              this.msg.error(resBody.message)
              return throwError(event);
            }
          }
          // 若一切都正常,则后续操作
          return of(event);
        }),
        catchError((err: HttpErrorResponse) => {
          this.handleData(err);
          // 返回错误处理
          return throwError(err);
        }),
      );
  }

  private handleData(
    event: HttpResponse<any> | HttpErrorResponse,
  ): Observable<any> {
    // 可能会因为 `throw` 导出无法执行 `_HttpClient` 的 `end()` 操作
    // this.injector.get(_HttpClient)
    //   .end();
    // 业务处理:一些通用操作
    switch (event.status) {
      case 200:
        break;
      case 400: // 参数错误
        if (event instanceof HttpErrorResponse) {
          if (event.error) {
            this.msg.error('错误的请求,由于语法错误,该请求无法完成');
          }
        }
        break;
      case 401: // 未登录状态码
        break;
      case 403:
      // case 404:
      case 500:
        // forbidden force redirect to error page temporarily.
        const errorEvent: any = event;
        if (errorEvent?.error?.message) {
          this.msg.error(`${errorEvent.error.message}`);
        } else if (errorEvent.error instanceof ArrayBuffer) {
          const dataView = new DataView(errorEvent.error);
          const decoder = new TextDecoder('utf8');
          const error = JSON.parse(decoder.decode(dataView));
          this.msg.error(`${error.message}`);
        } else {
          this.msg.error(`${event.status}: ${errorEvent.url}`);
        }
        break;
      default:
        if (event instanceof HttpErrorResponse) {
          this.msg.error(event.message);
        }
        break;
    }
    return of(event);
  }
}