![](/img/trans.png)
[英]Angular 4 Http Interceptor: next.handle(…).do is not a function
[英]Angular HTTP Interceptor subscribing to observable and then returning next.handle but throwing TypeError: You provided 'undefined'
我有一個 HTTP 攔截器,在每次請求之前,我檢查訪問令牌是否已過期,如果是,我從我的服務訂閱 http.post 調用,然后訂閱它,當我獲得新的訪問令牌時,我將調用下一個。像這樣處理(請求):
this.auth.refreshAccessToken().subscribe((token: string) => {
this.auth.newAccessToken = token;
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next.handle(request);
});
問題是它拋出TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
is TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
這讓我覺得我在那里打錯了 http.post 調用。
編輯 1:我還沒有機會徹底測試這個,但到目前為止似乎一切正常。 在返回整個地圖之前我有一個 console.log 但它沒有觸發,但是,其他一切都有效,並且每次我獲得新的訪問令牌並且 DID 發生時,我都會在任何地方更新 currentUser/權限,因此出於所有意圖和目的,它似乎工作,這是更新的代碼:
mergeMap(token => {
this.auth.newAccessToken = token;
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next.handle(request);
})
您不會在攔截器內subscribe()
,而是返回Observable<HttpEvent<any>>
。 這可以通過使用 RxJS 可管道操作符( 'rxjs/operators'
)來完成,例如tap (用於設置newAccessToken
等newAccessToken
)和switchMap或mergeMap與pipe()
結合使用,返回Observable<HttpEvent<any>>
類型的Observable<HttpEvent<any>>
滿足HttpInterceptor接口:
import { Injectable } from '@angular/core';
import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { switchMap, tap } from 'rxjs/operators';
import { AuthService } from './auth.service';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private auth: AuthService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.auth.refreshAccessToken().pipe(
tap(token => this.auth.newAccessToken = token), // side effect to set token property on auth service
switchMap(token => { // use transformation operator that maps to an Observable<T>
const newRequest = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next.handle(newRequest);
})
);
}
}
這是一個實際的例子。 請查看日志以查看正在注銷的關鍵信息。
希望這有幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.