Javascript 在Angular 7 http拦截器中选择右RxJs运算符
我是RxJs的新手,如果您能建议我在拦截器中使用哪个操作符,我将不胜感激。 如果会话即将结束,我需要执行异步请求以刷新身份验证令牌:Javascript 在Angular 7 http拦截器中选择右RxJs运算符,javascript,rxjs,angular6,angular7,Javascript,Rxjs,Angular6,Angular7,我是RxJs的新手,如果您能建议我在拦截器中使用哪个操作符,我将不胜感激。 如果会话即将结束,我需要执行异步请求以刷新身份验证令牌: intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req) .pipe( //catchError operator work
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req)
.pipe(
//catchError operator works good, everything's ok here
catchError((error: HttpErrorResponse) => {
if (error instanceof HttpErrorResponse) {
let refreshToken = localStorage.getItem("refreshToken");
if (error && error.status === 401 && refreshToken) {
// 401 errors are most likely going to be because we have an expired token that we need to refresh.
if (this.refreshTokenInProgress) {
// If refreshTokenInProgress is true, we will wait until refreshTokenSubject has a non-null value
// which means the new token is ready and we can retry the request again
return this.refreshTokenSubject.pipe(
filter(result => result !== null),
take(1),
switchMap(() => next.handle(this.authRequest(req)))
);
}
else {
this.refreshTokenInProgress = true;
// Set the refreshTokenSubject to null so that subsequent API calls will wait until the new token has been retrieved
this.refreshTokenSubject.next(null);
return this.backend.auth.refreshToken().pipe(
switchMap((res) => {
if (res) {
//...
return next.handle(this.authRequest(req));
}
else {
this.backend.auth.logOut();
window.location.reload();
}
}),
// When the call to refreshToken completes we reset the refreshTokenInProgress to false
// for the next time the token needs to be refreshed
finalize(() => this.refreshTokenInProgress = false)
);
}
}
else {
this.refreshTokenInProgress = false;
//...
return throwError(error.error);
}
}
}),
//The problem is here, I'm not sure which operator to use to handle successfull response
tap(event => {
if (event instanceof HttpResponse) {
if ((this.backend.auth.getAccessCookieExpireDate())) {
let diffMin = 0;
let diffMs = (Date.parse(this.backend.auth.getAccessCookieExpireDate()) - Date.parse(new Date().toUTCString()));
diffMin = Math.round(((diffMs % 86400000) % 3600000) / 60000);
if (diffMin <= 10) {
//refresh token automatically before it dies
let refreshToken = localStorage.getItem("refreshToken");
if (refreshToken) {
//this async request is not called, can't see it in network
this.backend.auth.refreshToken().pipe(
tap((res) => {
if (res) {
//...
}
else {
this.backend.auth.logOut();
window.location.reload();
}
})
);
}
}
}
}
})
);
}
intercept(req:HttpRequest,next:HttpHandler):可观察{
返回下一个句柄(req)
.烟斗(
//catchError运算符工作正常,这里一切正常
catchError((错误:HttpErrorResponse)=>{
if(HttpErrorResponse的错误实例){
让refreshToken=localStorage.getItem(“refreshToken”);
if(error&&error.status==401&&refreshToken){
//401错误很可能是因为我们有一个过期的令牌需要刷新。
如果(本程序中的refreshTokenInProgress){
//如果refreshTokenInProgress为true,我们将等待refreshTokenSubject具有非null值
//这意味着新令牌已准备就绪,我们可以再次重试请求
返回此.refreshTokenSubject.pipe(
过滤器(结果=>result!==null),
以(1)为例,
switchMap(()=>next.handle(this.authRequest(req)))
);
}
否则{
this.refreshTokenInProgress=true;
//将refreshTokenSubject设置为null,以便后续API调用将等待直到检索到新令牌
this.refreshTokenSubject.next(null);
返回此.backend.auth.refreshToken()管道(
开关图((分辨率)=>{
如果(res){
//...
返回next.handle(this.authRequest(req));
}
否则{
this.backend.auth.logOut();
window.location.reload();
}
}),
//当对refreshToken的调用完成时,我们将refreshTokenInProgress重置为false
//下一次需要刷新令牌时
完成(()=>this.refreshTokenInProgress=false)
);
}
}
否则{
this.refreshTokenInProgress=false;
//...
返回投掷器(error.error);
}
}
}),
//问题就在这里,我不确定使用哪个操作符来处理成功响应
点击(事件=>{
if(HttpResponse的事件实例){
if((this.backend.auth.getAccessCookieExpireDate()){
设diffMin=0;
让diffMs=(Date.parse(this.backend.auth.getAccessCookieExpireDate())-Date.parse(new Date().toutString());
diffMin=数学舍入((diffMs%86400000)%3600000)/60000);
if(diffMin您可以使用switchMap
对可观察事件进行映射,并在末尾对传入事件进行映射
switchMap(事件=>{
if(HttpResponse的事件实例){
//...
返回此.backend.auth.refreshToken()管道(
地图(res=>{
//...
返回事件;
})
);
}
(事件)的返回;
})
我如何使所有路径返回事件?否则我会得到错误类型void不可分配给类型ObservableInput…
@GyuzalR使用的将输入作为ObservableInput返回。