HttpInterceptor内で401エラーがキャッチされたときに、特定のルートにナビゲートすることは可能ですか?
私がやろうとしたことは:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req)
.do((event: HttpEvent<any>) => {}, (error: any) => {
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
this.router.navigate(['/signin']);
}
}
});
}
しかし、何も起こっていません。
サインインページにリダイレクトできるのは、
window.location.href = '/signin';
の代わりに
this.router.navigate(['/signin']);
はい、可能です。Angular 4&5で試してみてください。
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { HttpRequest, HttpResponse, HttpErrorResponse, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { AuthHelperService } from '../main/content/authentication/auth-helper.service';
@Injectable()
export class UnauthorizedInterceptor implements HttpInterceptor {
constructor(private authHelperService: AuthHelperService, private router: Router ) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// If required, here we can do any stuff with the response getting from API.
console.log('Common place to handle 1 response');
}
})
.catch(error => {
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
//when the API service return any 401-Unauthorized error control come here,
//Call logoutUser to clear and redirect to login page.
console.log('Handle 401');
this.authHelperService.logoutUser();
//this.router.navigate(['auth/login']); //You can Navigate to the router directly, in this example it will be done in authHelperService.
}
return Observable.throw(error);
}else{
return Observable.throw(error);
}
});
}
}
以下はサービスコードです。エラーの場合はResolve()を確認してください。そうしないと、ハング状態になります。
getFaqs(): Promise<any[]>
{
return new Promise((resolve, reject) => {
const body = '';
this.http.post('http://localhost:3000/faq/faqs', body)
//Map is a handler to parse the response, subscribe will get parsed value as the result. Error has been gloably handled, by HTTP Intercepter.
.map((res:Response)=>res)
.subscribe(
(result: any) => {
//console.log('faq/faqs Service Response : ' + JSON.stringify(result));
this.faqs = result.data;
this.onFaqsChanged.next(this.faqs);
resolve(this.faqs);
},
(error)=>{
console.log('ERROR CAME HERE');
resolve();
}
);
});
}
これを行うには、rxjsのcatch演算子を使用できます。
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.catch((error, source) => {
if (error instanceof HttpErrorResponse &&
error.status == 401 &&
!error.url.includes("/signin")) {
this.router.navigate(["/signin"]);
return Observable.empty();
}
else {
return Observable.throw(error);
}
});
}
_location.href
_への割り当ては、次のようになります。
this.router.navigateByUrl('/signin');
navigate
メソッドはルーターを取りますコマンドパスではありません。