【问题标题】:Proper workflow to handle 401 error on Ionic 3 app在 Ionic 3 应用程序上处理 401 错误的正确工作流程
【发布时间】:2017-09-29 10:40:27
【问题描述】:

我需要在我的Ionic 3 应用程序上正确处理401 错误。当应用程序几天未使用并且该用户尝试访问该应用程序之后,会出现下面提到的错误。这个应用程序有一个后端 Web API(django),它使用jwt 令牌来验证用户。

那么你能告诉我在Ionic 3 应用程序上处理这种用例的正确工作流程吗?我无法找到好的资源来在网上引用这个。如果你有什么要分享的,那就太好了。

我看到this URL 提到了subscribe subjects。但我不知道如何用 Ionic 应用程序实现这样的事情。请问有什么线索吗?

authProvider.ts

import { Injectable, } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Headers, RequestOptions, BaseRequestOptions } from '@angular/http';
import { Storage } from '@ionic/storage';



 createHeader(headers: Headers) {
        return new Promise((resolve, reject) => {
            this.storage.get('loggedInUser')
                .then((token: any) => {
                    if (token) headers.append('Authorization', 'token ' + token.token);
                    resolve(headers);
                }, err => {
                    resolve(headers);
                });
        });
    }

 get(api) {
        return new Observable(observer => {
            let header = new Headers();
            this.createHeader(header)
                .then(() => {
                    let options = new BaseRequestOptions();
                    options.withCredentials = true;
                    options.headers = header;
                    this.http.get(api, options)
                        .subscribe(response => {
                            observer.next(response);
                            observer.complete();
                        }, (e) => {
                            observer.error(e);
                        });
                })
        })
    }

控制台错误信息:

【问题讨论】:

  • 你使用的是Http,而不是HttpClient,对吧?
  • @n00dl3 我正在使用这个模块import { Http } from '@angular/http';

标签: angular typescript ionic2 ionic3


【解决方案1】:

retryWhen 救援!

如果您想在解决问题(例如更新令牌左右)后重试呼叫,retryWhen() 是您的最佳选择。

public retryWhen(notifier: function(errors: Observable): Observable): Observable

返回一个镜像源 Observable 的 Observable,但错误除外。如果源 Observable 调用错误,该方法会将导致错误的 Throwable 发送到通知器返回的 Observable。

如果 Observable 调用完成或错误,则此方法将在子订阅上调用完成或错误。否则此方法将重新订阅源 Observable。

tldr :该操作符将处理错误,如果notifier 函数返回的可观察对象发出一个值,将重新订阅前一个可观察对象。但是,如果notifier 发出的 Observable 抛出错误,则会传播错误。

get(api) {
  let header = new Headers();
  return Observable.fromPromise(this.createHeader(header))
  .map(()=>{
    let options = new BaseRequestOptions();
    options.withCredentials = true;
    options.headers = header;
    return options
  })
  .switchMap((options)=>this.http.get(api, options))
  .retryWhen((errors)=>errors.switchMap((err:Error| Response)=>{
    if(err instanceof Response && err.status===401){
      // handle 401
      return this.someHandlingReturningAnObservable();
    }
    return Observable.throw(err);
  }));
}

这里,this.someHandlingReturningAnObservable() 返回一个 Observable。在这种方法中,你解决了你的问题(要求一个新的令牌等),当它发出它的值时,可观察的链将被重放。只是不处理非 401 错误。

@987654330 可以的话@我

如果您只想处理错误而不做任何其他事情(例如显示错误页面),您可以使用catch() 运算符:

public catch(selector: function): Observable

通过返回一个新的来捕获要处理的 observable 上的错误 可观察或抛出错误。

get(api) {
  let header = new Headers();
  return Observable.fromPromise(this.createHeader(header))
  .map(()=>{
    let options = new BaseRequestOptions();
    options.withCredentials = true;
    options.headers = header;
    return options
  })
  .switchMap((options)=>this.http.get(api, options))
  .catch((err:Error| Response)=>{
    if(err instanceof Response && err.status===401){
      // handle 401
      return this.someHandlingReturningAnObservable();
    }
    return Observable.throw(err);
  });
}

【讨论】:

  • 你能告诉我retryWhenoperatormodule吗?
  • 我不确定我是否理解你的问题,但是import "rxjs/add/operator/retryWhen" ?
  • 是的。现在可以了。但这是什么someHandlingReturningAnObservable?我需要写这个方法吗?我需要在app.component.ts(根)文件中捕获此错误,并且需要显示toast 消息或将用户重定向到login 页面。请问有什么线索吗?
  • 然后转到catch() 部分someHandlingReturningAnObservable() 是您将用来处理错误的方法,您必须实施它,是的,这是您将显示toast 和/或重定向的地方。请注意,它必须返回一个 observable(但它可以是 Observable.empty())。
  • 好的。在 Ionic 工作流程中,我必须在组件内完成。所以我可以在这里发出 event 并在 app 组件内捕获它吗?然后我就可以随心所欲地处理了。
猜你喜欢
  • 2019-05-04
  • 2014-09-14
  • 2018-01-17
  • 2015-08-12
  • 1970-01-01
  • 2019-01-30
  • 2017-05-05
  • 2010-12-02
  • 1970-01-01
相关资源
最近更新 更多