Angular基础操作之—— Http interceptor

拦截器是一种很常用的东西,作用有很多,比如说设置Http请求头,处理Http请求返回数据,统一错误处理等,angualr里也有拦截器 HttpInterceptor

先实现一个最基本的拦截器

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpEvent, HttpRequest, HttpHandler } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class CustomInterceptor implements HttpInterceptor {
  public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log('拦截成功');
    return next.handle(req);
  }
}

这个拦截器什么操作也没做,只是单纯的拦截

要使拦截器生效,需要在app.module.ts里注入

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

import { AppComponent } from './app.component';

import { CustomInterceptor } from './http-interceptors/customInterceptor';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: CustomInterceptor, multi: true }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

测试一下

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  constructor(private http: HttpClient) {}

  ngOnInit(): void {
    this.getData();
  }

  getData() {
    this.http.get('assets/config.json').subscribe((data) => {
      console.log('获取数据成功', data);
    })
  }

}

拦截成功了

处理Http请求头 (Http Request Headers Interceptor)

通常我们处理http请求的时候,需要在请求头中加入一些身份验证信息,比如说token,我们可以通过拦截器为所有的请求加上token信息

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class HeaderInterceptor implements HttpInterceptor {

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(this.addToken(req, 'my token'));
    }

    addToken(req: HttpRequest<any>, token: string): HttpRequest<any> {
        return req.clone({ headers: req.headers.set('Authorization', token) });
        // 又或者是 req.clone({ setHeaders: { Authorizetion: token } });
    }
}

然后也要把这个拦截器注入到app.module.ts 里,它才会生效

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

import { AppComponent } from './app.component';

import { CustomInterceptor } from './http-interceptors/customInterceptor';
import { HeaderInterceptor } from './http-interceptors/headerInterceptor';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: CustomInterceptor, multi: true },
    { provide: HTTP_INTERCEPTORS, useClass: HeaderInterceptor, multi: true },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

看一下请求头,已经生效了

处理Http响应 (Http Response Interceptor)

有的时候我们需要对请求返回的数据处理一下,比如添加一个id,再新建一个响应拦截器

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class ResponseHandlerInterceptor implements HttpInterceptor {

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(req).pipe(
          map((event) => {
            if (event instanceof HttpResponse && event.status === 200) {
              event.clone({ body: this.addId(event.body) });
            }
            return event;
          })
        )
    }

    addId(data: any) {
      data.forEach((item: any, index: any) => {
        item.id = index;
      })
    }
}

再把它注入到app.module.ts 里,看一下效果

 Id已经成功添加

Http错误处理(Http Error Interceptor)

在Http请求中,我们需要对错误情况进行统一处理,这时候,我们也可以借助拦截器实现(错误提示或重试等)

新建一个错误处理拦截器

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';

@Injectable()
export class ErrorHandlerInterceptor implements HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(req).pipe(
            catchError(error => {
                console.log('请求');
                let text = '请求失败';
                switch (error.status) {
                    case 401:
                        text = ''
                        break;
                    case 403:
                      text = ''
                        break;
                }
                return throwError(() => text);
            }),
            retry(3)
        );
    }
}

把它也注入到app.module.ts 里之后,拦截器生效了 

可以看到请求一共发起了4次,第一次失败了之后retry(3)又重新发起了3次请求,最后都失败了之后,抛出错误,retry(3)括号里是几就重新发起几次请求, 而在switch里我们可以对不同的错误情况做出相应处理

最后,如果我们有多个拦截器,一个个注入到app.module.ts里有点麻烦,我们可以把拦截器导入到一个文件里,再把这个文件注入到app.module.ts里,会方便一些

import { HTTP_INTERCEPTORS } from '@angular/common/http';

import { CustomInterceptor } from './customInterceptor';
import { HeaderInterceptor } from './headerInterceptor';
import { ResponseHandlerInterceptor } from './responseHandlerInterceptor';
import { ErrorHandlerInterceptor } from './errorHandlerInterceptor';

export const httpInterceptorProviders = [
  { provide: HTTP_INTERCEPTORS, useClass: CustomInterceptor, multi: true },
  { provide: HTTP_INTERCEPTORS, useClass: HeaderInterceptor, multi: true },
  { provide: HTTP_INTERCEPTORS, useClass: ResponseHandlerInterceptor, multi: true },
  { provide: HTTP_INTERCEPTORS, useClass: ErrorHandlerInterceptor, multi: true },
];


import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app.component';

import { httpInterceptorProviders } from './http-interceptors/index';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [
    httpInterceptorProviders
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值