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

标签 angular typescript ionic2 ionic3

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

那么你能告诉我在 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);
                        });
                })
        })
    }

控制台错误消息:

enter image description here

最佳答案

retryWhen 拯救!

如果您想在修复问题(例如更新 token 等)后重试调用,retryWhen() 是可行的方法。

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

Returns an Observable that mirrors the source Observable with the exception of an error. If the source Observable calls error, this method will emit the Throwable that caused the error to the Observable returned from notifier.

If that Observable calls complete or error then this method will call complete or error on the child subscription. Otherwise this method will resubscribe to the source Observable.

tldr :此运算符将处理错误,如果 notifier 函数返回的 observable 发出值,将重新订阅之前的 Observable。但是,如果 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。在这种方法中,你解决了你的问题(请求一个新的 token 等),当它发出它的值时,可观察链将被重放。只是不处理非 401 错误。

catch() 如果可以的话我

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

public catch(selector: function): Observable

Catches errors on the observable to be handled by returning a new observable or throwing an error.

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);
  });
}

关于angular - 处理 Ionic 3 应用程序 401 错误的正确工作流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46362042/

相关文章:

angular - 如何从 Angular 属性绑定(bind)加载框架资源

typescript - 如何使用 Angular 2 和 Reactive 监听 css 动画的结束

angular - 我如何跟踪 ionic 2 中 app.component.ts 中的每个错误

cordova - fcm.onNotification() 在应用程序处于后台时不会在点击通知时被调用

angular - Observable.if 工作不正常

javascript - JSON 到 Excel 的转换

angular - 在响应式表单中初始化 FormGroup 的位置?

angular - 如何在 Angular 中使用 import { onError } from 'apollo-link-error' 来处理所有错误

javascript - 在 Typescript 中,是否可以使 Javascript 对象的属性名称接受多个值?

angular - 在 typescript 中找不到名称 'exports' 错误