Angular中实现全局拦截器

骑驴找蚂蚁 · 2021年08月25日 · 阅读 43

​ 有时候需要在请求之前或者之后做一些通用的操作,如在请求头上添加一个token头,还有处理转换url地址。这时候就需要为请求加上拦截器。如果你经常使用spring 相信你也不会陌生,在angular中使用拦截器也非常的简单几乎和spring一样的。

实现拦截器

在实现拦截器之前我们需要创建一个自己的拦截器类。创建一个名为HttpRequestInterceptor的拦截器内容如下:

import { Injectable } from '@angular/core';
import {
  HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse
} from '@angular/common/http';
import {NbAuthService, NbAuthToken} from '@nebular/auth';

import {Observable} from 'rxjs';
import {tap} from 'rxjs/operators';
import {Router} from '@angular/router';
import {environment} from "../../environments/environment";

/** Inject With Credentials into the request */
@Injectable()
export class HttpRequestInterceptor implements HttpInterceptor {

  token: string

  public constructor(
    public router: Router,
    public authService: NbAuthService
  ) {
    this.authService.onTokenChange().subscribe((token: NbAuthToken) => {
      this.token = token.toString()
    })
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log('interceptor: ' + req.url);

    req = req.clone({
      url: req.url.indexOf('http') == 0 ? req.url : environment.gateway + "/backend" + req.url,
      withCredentials: false,
      setHeaders: {
        'X-Requested-With': 'XMLHttpRequest',
        'Authorization': this.token,
      }
    });
    return next.handle(req).pipe(
      tap(
        () => {},
        (error: any) => {
          if (error instanceof  HttpErrorResponse) {
            if (error.status !== 401) {
              return;
            }
            this.router.navigate(['/auth/login']).then(r => {
              console.log(r);
            });
          }
        }
      )
    );
  }
}

拦截器类只需要实现HttpInterceptor接口即可。上述代码是我项目的一个拦截器类,它主要的功能就是:

  • 获取本地当前的登录token
  • 修改请求的url地址
  • 添加两个http
  • 检查结果状态为401就跳转到授权页面。

接下来就是最重要的一步,将拦截器类加入到providers中。我们加入到app.module.ts文件的providers中。

@NgModule({
  declarations: declarations,
  imports: [
  ],
  providers: [
  	// 加入这行就是添加了一个全局拦截器
    {
      provide: HTTP_INTERCEPTORS, useClass: HttpRequestInterceptor, multi: true
    },
  ],
  entryComponents: [
  ]
})
export class AppModule {
  constructor(private injector: Injector) {
  }
  ngDoBootstrap(applicationRef: ApplicationRef) {
    AppInjector.setInjector(this.injector);
    applicationRef.bootstrap(AppComponent);
  }
}

你可以从这里获取到源码。

关于作者

全栈工程师

文章被阅读 118.3k
获赞 11

文章目录