import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { timeout, delay, retryWhen, scan, tap, catchError } from 'rxjs/operators';
import { mergeMap } from 'rxjs/operators';
import { AuthService } from '../service/auth-service/AuthService.service'
import { Router } from '@angular/router';
/** Pass untouched request through to the next request handler. */
import { MessageProvider } from "../tools/message";
/** 超时时间 */
const DEFAULTTIMEOUT = 5000;
/** 最大重试次数 */
const MAXRETRYCOUNT = 3;
/** 防止重复点击 网络重复请求 */
const MAXDEBOUNCETIME = 1000;
@Injectable()
export class NoopInterceptor implements HttpInterceptor {
constructor(
private authService: AuthService,
private router: Router,
private messagePvd: MessageProvider
) {
};
intercept(req: HttpRequest<any>, next: HttpHandler):Observable<HttpEvent<any>> {
// console.log('test ckick3');
let time = new Date().getTime();
let accessToken: string = this.authService.getAuthToken() ? this.authService.getAuthToken() : "";
const authReq = req.clone({
setHeaders: {
// REQUEST_FROM: "WEB_OFFICIAL",
Ver: "1.0.17",
TIMESTAMP: time.toString(),
ACCESS_TOKEN: accessToken,
Authentication: "web:fkasfklasjfklwejiwefsklfsjfiwej="
}
});
// ACCESS_TOKEN:accessToken}});
return <any>next.handle(authReq).pipe(
debounceTime(MAXDEBOUNCETIME),
timeout(DEFAULTTIMEOUT),
retryWhen(err$ => {
// 重试
return err$.pipe(
scan((errCount, err) => {
if (errCount >= MAXRETRYCOUNT) {
throw err;
}
return errCount + 1;
}, 0),
delay(1000),
tap(errCount => {
// 副作用
if (errCount == 1) {
// 第一次重试时,提示用户
this.messagePvd.errorMsg('网络超时,正在重新请求中...');
}
})
)
}),
catchError((err: HttpErrorResponse) => {
this.messagePvd.errorMsg('网络超时, 请重试');
return throwError('网络超时' + err.name + err.message)
}),
mergeMap((event: any) => {
if (event instanceof HttpResponse && event.status != 200) {
return Observable.create(event);
}
if (event instanceof HttpResponse && event.body.code == 2) {
this.messagePvd.errorMsg(event.body.msg);
this.router.navigate(['/passport']);
return Observable.create(event);
}
if (event instanceof HttpResponse && event.body.code != undefined && event.body.code != 0) {
this.messagePvd.errorMsg(event.body.msg);
return Observable.create(event);
}
return Observable.create(observer => observer.next(event)); //请求成功返回响应
}),
catchError((err: HttpErrorResponse) => {
switch (err.status) {
case 401:
this.messagePvd.errorMsg('服务器错误代码:401');
console.log(err);
break;
case 403:
this.messagePvd.errorMsg('服务器错误代码:403');
console.log(err);
break;
case 404:
this.messagePvd.errorMsg('服务器错误代码:404');
console.log(err);
break;
case 500:
this.messagePvd.errorMsg('服务器错误代码:500');
console.log(err);
break;
case 502:
this.messagePvd.errorMsg('服务器错误代码:502');
console.log(err);
break;
default:
console.log(err);
break;
}
return throwError(err.status);
})
);
}
}
注意:
1.这是自己根据网上各种大神的拦截器copy过来,改造的拦截器,不足请指正
2.MessageProvider 是自己封装的消息弹出系统,拷贝过去不能使用,直接删除相关代码即可,不影响使用
3. https://angular.cn/guide/http#intercepting-requests-and-responses