在Ionic 3应用程序上处理401错误的正确工作流程

Sam*_*ath 3 typescript ionic2 ionic3 angular

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

那么你能告诉我在Ionic 3app 上处理这种用例的正确工作流程吗?我无法找到很好的资源来在网上推荐这个.如果你有分享的东西,那就太好了.

我已经看到了它提到的这个URLsubscribe subjects.但我不知道如何使用Ionic app实现这样的功能.有什么线索吗?

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);
                        });
                })
        })
    }
Run Code Online (Sandbox Code Playgroud)

控制台错误消息:

在此输入图像描述

n00*_*dl3 5

retryWhen 救援!

如果您想要修复一些东西(比如更新令牌等),retryWhen()则需要重试呼叫.

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

返回一个Observable,它反映了源Observable,但错误除外.如果源Observable调用错误,则此方法将发出导致错误的Throwable到通知程序返回的Observable.

如果Observable调用complete或error,则此方法将调用子订阅的完成或错误.否则此方法将重新订阅源Observable.

tldr:此运算符将处理错误,如果notifier函数返回的observable 发出值,则将重新订阅前一个Observable.但是,如果发出的Observable notifier抛出错误,则会传播错误.

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);
  }));
}
Run Code Online (Sandbox Code Playgroud)

在这里,this.someHandlingReturningAnObservable()返回一个Observable.在此方法中,您可以修复问题(请求新标记等),当它发出其值时,将重放可观察链.不处理非401错误.

catch() 我,如果可以的话

如果您只想处理错误而不再执行任何操作(例如显示错误页面),您可以使用catch()运算符:

public catch(selector: function): Observable

通过返回新的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);
  });
}
Run Code Online (Sandbox Code Playgroud)