在angular4 项目中,每次请求服务端须要添加头部信息AccessToken做为认证的凭据。但若是在每次调用服务端就要写代码添加一个头部信息,会变得很麻烦。能够使用angular4的HttpClient来拦截每一个请求,而后在头部添加上信息。git
直接上代码实践github
1、建立拦截器Service,实现HttpInterceptor的intercept方法api
import { Injectable, Injector} from '@angular/core'; import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http'; import {Observable} from 'rxjs/Observable'; import 'rxjs/add/operator/do'; import {AuthenticationService} from './auth/authentication.service'; // 用于得到AccessToken的服务类 import {environment} from '../../environments/environment'; /** * HTTP拦截器,设置头部信息 */ @Injectable() export class BaseHttpInterceptorService implements HttpInterceptor { authService: AuthenticationService; skipAuth: [string]; constructor(private inject: Injector) { // 用户登陆或认证请求则不须要添加头部AccessToken信息 this.skipAuth = [ `${environment.serverUrl}/api/v1/User/login`, ]; } /** * 拦截器拦截请求 * @param {HttpRequest<any>} req * @param {HttpHandler} next * @returns {Observable<HttpEvent<any>>} */ intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { this.authService = this.inject.get(AuthenticationService);// 注意此句 const req_started = Date.now(); let authReq; /** * 若是是跳过认证的连接,则不添加头部信息 */ if (this.isSkipAuth(req.url)) { authReq = req.clone(); }else { const access_token = `Bearer ${this.authService.getAccessToken('563151811@qq.com')}`; authReq = req.clone({ setHeaders: { Authorization: access_token } }); } return next.handle(authReq).do(event => { if (event instanceof HttpResponse) { const elapsed = Date.now() - req_started; console.log(`Request for ${req.urlWithParams} took ${elapsed} ms`); } }); } /* *是否跳过添加头部认证 */ isSkipAuth(url: string) { let isMatch = false; this.skipAuth.forEach((reg_url: string) => { if ( !isMatch) { if (url.search(reg_url) >= 0) { isMatch = true; } } }); return isMatch; } }
2、注册拦截器,在APPModule中,添加以下代码angular4
{ provide: HTTP_INTERCEPTORS, useClass: BaseHttpInterceptorService,// 上边定义的拦截器名字 multi: true },
3、每一个请求服务端数据的Service依赖HttpClient,而不是http。ide
那么一个基础的拦截器已经完成了,可是,你会发现调用认证服务Service的时候,会报错:Cyclic dependency error with HttpInterceptor ,若是添加了第一步代码中注意点那段代码后,又会发现OK了。this
这是依赖注入循环嵌套:A依赖B,B中又引用A。url
官方文档中采用forwardRef,可是发现没用。在Stack Overflow中看到有人采用上述方法成功解决问题。https://github.com/angular/angular/issues/18224spa
如须要更详细的代码或有问题,请联系我code