angular4 + http拦截器

http拦截器的使用主要用于http请求,比如设置http请求头,常用于header中包含token或者cookie,以及设置请求方式为 application/x-www-form-urlencoded 或 application/json等,也可以对请求的api进行拦截。

在angular4中使用 @angular/common/http进行http请求,来做拦截器,相关代码如下:

InterceptorService.ts(此处为ionic3框架使用的方法,angular4 WEB请看下一个实例代码)


// http 请求拦截器
import { Injectable } from '@angular/core'
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'
import { Observable } from 'rxjs'
import { catchError } from 'rxjs/operators'
import { _throw } from 'rxjs/observable/throw'
import { NativeStorage } from '@ionic-native/native-storage'
import { Utils } from './utils'

@Injectable()
export class InterceptorService implements HttpInterceptor{
    private timeout = 1000 * 30 // 30s超时
    private timer = 0
    constructor(
        private utils: Utils,
        private storage: NativeStorage){}
    intercept(request: HttpRequest<any>, next: HttpHandler) : Observable<HttpEvent<any>>{
        // 排除不需要进行token验证的接口
        let excludeUrl = ['login', 'logout']
        let isNotVerifyToken = false
        excludeUrl.map(item => {
            if(request.url.indexOf(item) > -1) {
                isNotVerifyToken = true
            }
        })
        if(!isNotVerifyToken){
            // 此处使用promise的方式获取localstorage
            let promise = this.storage.getItem('token')
            return Observable.fromPromise(promise).mergeMap(token => {
                let cloneRequst = this.addToken(token, token)
                return next.handle(cloneRequst).timeout(this.timeout).pipe(
                    // 异常集中处理,只要请求有error就直接返回网络错误+状态code
                    catchError(error => {
                        // 简单的防抖,防止多次执行提示网络错误
                        clearTimeout(this.timer)
                        this.timer = setTimeout(() => {
                            let msg = '网络错误'
                            alert(msg)
                        }, 2000)
                        return _throw(error)
                    })
                )
            })
        }else {
            let cloneRequst = this.addToken(request)
            return next.handle(cloneRequst).timeout(this.timeout).pipe(
                // 异常集中处理,只要请求有error就直接返回网络错误+状态code
                catchError(error => {
                    // 简单的防抖,防止多次执行提示网络错误
                    clearTimeout(this.timer)
                    this.timer = setTimeout(() => {
                        let msg = '网络错误'
                        alert(msg)
                    }, 2000)
                    return _throw(error)
                })
            )
        }
    }

    private addToken(request: HttpRequest<any>, token?: any) {
        let req: HttpRequest<any>
        if(token) {
            req = request.clone({
                // 拦截所有请求,并且在header中增加响应头以及token
                setHeaders: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Authorization': token
                }
            })
        }else {
            // 当页面不需要在header中传递token时设置header
            req = request.clone({
                setHeaders: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            })
        }
        return req
    }
}

// http 请求拦截器
import { Injectable } from '@angular/core'
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'
import { Observable } from 'rxjs'
import { catchError } from 'rxjs/operators'
import { _throw } from 'rxjs/observable/throw'
import { NativeStorage } from '@ionic-native/native-storage'
import { Utils } from './utils'

@Injectable()
export class InterceptorService implements HttpInterceptor{
    private timeout = 1000 * 30 // 30s超时
    private timer = 0
    constructor(
        private utils: Utils,
        private storage: NativeStorage){}
    intercept(request: HttpRequest<any>, next: HttpHandler) : Observable<HttpEvent<any>>{
        // 排除不需要进行token验证的接口
        let excludeUrl = ['login', 'logout']
        let isNotVerifyToken = false
        excludeUrl.map(item => {
            if(request.url.indexOf(item) > -1) {
                isNotVerifyToken = true
            }
        })
        if(!isNotVerifyToken){
            // 此处使用promise的方式获取localstorage
            let token = localstorage.getItem('token')
            let cloneRequst = this.addToken(request, token)
            return next.handle(cloneRequst).timeout(this.timeout).pipe(
            // 异常集中处理,只要请求有error就直接返回网络错误+状态code
               catchError(error => {
                  // 简单的防抖,防止多次执行提示网络错误
                  clearTimeout(this.timer)
                  this.timer = setTimeout(() => {
                      let msg = '网络错误'
                      alert(msg)
                  }, 2000)
                  return _throw(error)
               })
             )
           })
        }else {
            let cloneRequst = this.addToken(request)
            return next.handle(cloneRequst).timeout(this.timeout).pipe(
                // 异常集中处理,只要请求有error就直接返回网络错误+状态code
                catchError(error => {
                    // 简单的防抖,防止多次执行提示网络错误
                    clearTimeout(this.timer)
                    this.timer = setTimeout(() => {
                        let msg = '网络错误'
                        alert(msg)
                    }, 2000)
                    return _throw(error)
                })
            )
        }
    }

    private addToken(request: HttpRequest<any>, token?: any) {
        let req: HttpRequest<any>
        if(token) {
            req = request.clone({
                // 拦截所有请求,并且在header中增加响应头以及token
                setHeaders: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Authorization': token
                }
            })
        }else {
            // 当页面不需要在header中传递token时设置header
            req = request.clone({
                setHeaders: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            })
        }
        return req
    }
}

app.modules.ts


//import部分加入以下代码
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
//@NgModule部分providers最后加入如下代码
{provide: HTTP_INTERCEPTORS, useClass: InterceptorService, multi: true}

直接使用如下代码进行http请求即可


this.http.post(url, body).subscribe(data => {
    if(data) {
        return data
    }else {
        return null
    }
  }, err => {
    return err
})

《angular4 + http拦截器》上的一个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注