【问题标题】:Catch 401 Exception in Angular2在 Angular2 中捕获 401 异常
【发布时间】:2017-02-13 17:19:25
【问题描述】:

当我尝试连接到未经授权的 URL 时,我会进入 Chrome:

zone.js:1274 POST http://localhost:8080/rest/v1/runs 401 (Unauthorized)
core.umd.js:3462 EXCEPTION: Response with status: 401 Unauthorized for URL: http://localhost:8080/rest/v1/runs

我的 Home 组件的代码是:

import {Component, OnInit} from '@angular/core';
import {Run} from "../_models/run";
import {Http, Response} from "@angular/http";
import {RunService} from "../_services/run.service";
import {Observable} from "rxjs";

@Component({
    moduleId: module.id,
    templateUrl: 'home.component.html'
})

export class HomeComponent implements OnInit{
    url: "http://localhost:8080/rest/v1/runs"
    username: string;
    runs: Run[];

    constructor(private http: Http, private runService: RunService) {

    }

    ngOnInit(): void {
        this.username = JSON.parse(localStorage.getItem("currentUser")).username;
        this.runService.getRuns()
            .subscribe(runs => {
                this.runs = runs;
            });
    }
}

这个组件使用这个服务:

import { Injectable } from '@angular/core';
import {Http, Headers, Response, RequestOptions, URLSearchParams} from '@angular/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map'
import {AuthenticationService} from "./authentication.service";
import {Run} from "../_models/run";

@Injectable()
export class RunService {
    url = "http://localhost:8080/rest/v1/runs";
    private token: string;

    constructor(private http: Http, private authenticationService: AuthenticationService) {

    }

    getRuns(): Observable<Run[]> {
        return this.http.post(this.url, JSON.stringify({ token: this.authenticationService.token }))
            .map((response: Response) => {
                console.log(response.status);
                if (response.status == 401) {
                    console.log("NOT AUTHORIZED");
                }

                let runs = response.json();
                console.log(runs);
                return runs;
            });
    }
}

捕获此 401 异常的正确方法是什么,我应该在哪里执行此操作? 在组件中还是在服务中?最终目标是在发生任何 401 响应时重定向到登录页面。

【问题讨论】:

    标签: exception angular http-status-code-401


    【解决方案1】:

    您很可能希望从您的 RunService 中抛出一个错误,该错误可能会被您的组件捕获,该组件可以路由到登录页面。下面的代码应该可以帮助你:

    在运行服务中:

    需要从rxjs导入catch操作符:

    import 'rxjs/add/operator/catch';
    

    您的 getRuns() 函数应该更改为

    getRuns(): Observable<Run[]> {
        return this.http.post(this.url, JSON.stringify({ token: this.authenticationService.token }))
            .map((response: Response) => {
                let runs = response.json();
                return runs;
            })
            .catch(e => {
                if (e.status === 401) {
                    return Observable.throw('Unauthorized');
                }
                // do any other checking for statuses here
            });
    

    然后组件中的 ngOnInit 将是:

    ngOnInit(): void {
        this.username = JSON.parse(localStorage.getItem("currentUser")).username;
        this.runService.getRuns()
            .subscribe(runs => {
                this.runs = runs;
            }, (err) => {
                if (err === 'Unauthorized') { this.router.navigateByUrl('/login');
            });
    }
    

    显然你会想要满足你自己的需求并根据需要进行更改,但是从 Http 捕获错误、抛出 Observable 错误并使用 err 回调来处理组件中的错误的过程应该解决你的问题。

    【讨论】:

    • 感谢它运行良好,我已经对您的答案表示赞同并进行了编辑。再次感谢
    • 感谢您,是否可以添加一个服务来检查所有其他请求并相应地重新定向,而不是为每个请求重复
    • 是的,你可以这样做 - 只需创建一个导入路由器的服务,创建一个类似于 handleRequestErrors(err) 的函数,然后在那里编写自定义重定向的代码。然后,无论您想做什么,都可以使用该服务,例如(err) =&gt; { this.errorHandler.handleRequestErrors(err); }
    • @peppermcknight 应该进入您的答案,因为避免重复代码至关重要。帮了我很多!谢谢
    • 我得到 status = 0 和 401,为什么?
    猜你喜欢
    • 2014-08-30
    • 2010-10-03
    • 2012-07-10
    • 1970-01-01
    • 2011-05-29
    • 2011-07-02
    • 2021-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多