加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angular – 如何在遇到故障后允许我的HTTP请求继续通过我的应用

发布时间:2020-12-17 06:59:40 所属栏目:安全 来源:网络整理
导读:我正在使用位于Angular 2顶部的Ionic 2. 我在我的应用程序中使用服务来处理所有API请求.其中一些请求带有Authorization标头.如果auth失败,我的API可以返回401,我正在通过向用户显示错误并将其导航到登录屏幕来处理它.这一切都很好,我发布了这些错误的事件,我
我正在使用位于Angular 2顶部的Ionic 2.

我在我的应用程序中使用服务来处理所有API请求.其中一些请求带有Authorization标头.如果auth失败,我的API可以返回401,我正在通过向用户显示错误并将其导航到登录屏幕来处理它.这一切都很好,我发布了这些错误的事件,我订阅了其他地方处理逻辑(因为我不能在服务中使用导航控制器).

api.js服务代码:

@Injectable()
export class Api {
  base_url: string = 'https://***.com';
  url: string = this.base_url + '/api/v1';
  authurl: string = this.base_url + '/oauth/token';
  grant_type: string = 'password';
  client_id: string = '1';
  client_secret: string = '***';
  access_token: string;

  constructor(
    public http: Http,private storage: Storage,public events: Events) {

    // Grab access token and store it
    storage.get('access_token').then((val) => {
      this.access_token = val;
    });
  }

  // Performs a GET request with auth headers
  get(endpoint: string,params?: any) {
    if(!params) {
      params = [];
    }
    params['grant_type'] = this.grant_type;
    params['client_id'] = this.client_id;
    params['client_secret'] = this.client_secret;

    let headers: Headers = this.getHeaders();

    return this.getApiToken().flatMap(data => {

      headers.append('Authorization','Bearer ' + data);

      let options = new RequestOptions({ headers: headers });

      // Support easy query params for GET requests
      if (params) {
        let p = new URLSearchParams();
        for (let k in params) {
          p.set(k,params[k]);
        }
        // Set the search field if we have params and don't already have
        // a search field set in options.
        options.search = !options.search && p || options.search;
      } 

      return this.http.get(this.url + '/' + endpoint,options)
        .catch((error: any) => {
          if (error.status === 500) {
            this.events.publish('api:generalError',error);
            return Observable.throw(new Error(error.status));
          }
          else if (error.status === 401) {
            this.events.publish('api:unauthorized',error);
            return Observable.throw(new Error(error.status));
          }
        });
    }).share();
  }
}

问题在于我在向get用户发出请求时向用户显示的“正在加载…”对话框.在调用该方法之前,我创建一个加载对话框,并在成功或失败时将其关闭.问题是我在api.js中没有任何这个范围,以便在捕获401或500时解雇它.

以下是我的逻辑示例:

let loader = this.loadingCtrl.create({
  content: "Please wait..."
});
loader.present();

this.trainingProgramme.get_programmes()
  .map(res => res.json())
  .subscribe((res) => {

  this.currentItems = res.training_programmes;

},(err) => {
  // Error
  console.log(err);
},() => {
  loader.dismiss();
});

我认为这不重要,但我也为每个实体提供服务,而这些服务又调用api.js服务.在上面的例子中,这是this.trainingProgramme,如下所示:

get_programmes() {
    let seq = this.api.get('training-programmes');

    seq
      .subscribe();

    return seq;
  }

我认为我接近这一点的方式都是正确的,但是我看不出能够处理“加载”问题的方法.

是否有一种方法可以让我的应用程序中的get方法在捕获错误后继续,以便我的loader.dismiss()代码在正确的范围内运行?

我真的不想在服务中使用加载器(不确定我甚至能够?)因为这看起来像是糟糕的设计,我不想总是显示一个加载器,所以它属于控制器.

解决方法

你需要的是.finally运算符,即使Observable出错,它也会一直执行.

如果发生错误,则不会触发完整的回调(.subscribe调用的最后一个回调).

请记住包含它:

import 'rxjs/add/operator/finally';

...

this.trainingProgramme.get_programmes()
 .finally(() => loader.dismiss())
 .map(res => res.json())
 .subscribe((res) => {
   ...
 },(err) => {
  // Error
  console.log(err);
 });

顺便说一句,考虑将代码从@ angular / http更新到新的HttpClient.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读