web-dev-qa-db-ja.com

HttpInterceptor内のルートナビゲーション

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']);
6
manuel

はい、可能です。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);
            }
        });
}
1
Matt

_location.href_への割り当ては、次のようになります。

this.router.navigateByUrl('/signin');

navigateメソッドはルーターを取りますコマンドパスではありません。

1
André Werlang