Javascript 使用http拦截器设置来自ionic存储的默认请求标头-Angular 5-ionic 3

Javascript 使用http拦截器设置来自ionic存储的默认请求标头-Angular 5-ionic 3,javascript,angular,typescript,ionic2,ionic3,Javascript,Angular,Typescript,Ionic2,Ionic3,我正在尝试使用angular 5新HTTP客户端在所有请求头中设置令牌值。下面是我的代码: import {Injectable} from '@angular/core'; import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http'; import {Observable} from "rxjs/Observable"; import { Storage } from '@i

我正在尝试使用angular 5新HTTP客户端在所有请求头中设置令牌值。下面是我的代码:

import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
import {Observable} from "rxjs/Observable";
import { Storage } from '@ionic/storage';
import {Globals} from '../globals/globals';

@Injectable()
export class Interceptor implements HttpInterceptor {
  token: string;
  constructor(private storage: Storage, private global: Globals){ 
    this.storage.get('token').then((val) => {
      this.token = val;
    });
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log(this.token) //undefined "only for first time on app start"
    req = req.clone({
      setHeaders: {
        'Token': this.token,
        'Version': this.global.version,
      }
    });
    return next.handle(req);
  }
}
从'@angular/core'导入{Injectable};
从'@angular/common/http'导入{HttpEvent,HttpInterceptor,HttpHandler,HttpRequest};
从“rxjs/Observable”导入{Observable};
从'@ionic/Storage'导入{Storage};
从“../Globals/Globals”导入{Globals};
@可注射()
导出类拦截器实现HttpInterceptor{
令牌:字符串;
构造函数(专用存储:存储,专用全局:全局){
this.storage.get('token')。然后((val)=>{
this.token=val;
});
}
截取(req:HttpRequest,next:HttpHandler):可观察{
console.log(this.token)//未定义“仅在应用程序启动时第一次”
req=req.clone({
集合标题:{
“Token”:this.Token,
“版本”:this.global.Version,
}
});
返回next.handle(req);
}
}
虽然在请求头中添加令牌有效,但存在一个错误的异常。它第一次不起作用了。问题在于js async的性质,req.clone在从存储中获取令牌之前执行。由于Ionic storage返回promise,因此如何第一次处理这种情况?

您可以合并异步请求(获取令牌和处理请求),以便在令牌准备就绪后执行(而不是在构造函数中获取):

//-------------------------------------------------------------------------
//请注意,我使用的是可出租/可管道操作符(RxJS>5.5.x)
// https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md
// -------------------------------------------------------------------------
从“@angular/core”导入{Injectable};
从'@angular/common/http'导入{HttpEvent,HttpInterceptor,HttpHandler,HttpRequest};
从“rxjs/Observable”导入{Observable};
从'@ionic/Storage'导入{Storage};
从“../Globals/Globals”导入{Globals};
//新进口!
从'rxjs/observeable/fromPromise'导入{fromPromise};
从'rxjs/operators/mergeMap'导入{mergeMap};
@可注射()
导出类拦截器实现HttpInterceptor{
构造函数(私有存储:存储,私有全局:全局){}
承诺{
返回此.storage.get('token');
}
截取(req:HttpRequest,next:HttpHandler):可观察{
从promise(this.getToken()).pipe返回(
合并映射(令牌=>{
//在请求中使用令牌
req=req.clone({
集合标题:{
“令牌”:令牌,
“版本”:this.global.Version,
}
});
//处理请求
返回next.handle(req);
}));
}
}

Hi@sebafereras,谢谢你的帮助!不幸的是,它在
从Promise(this.getToken)返回时给了我错误。管道(
例如“():Promise”类型的
参数不能赋值给“():PromiseLike”属性类型的参数,那么“():Promise”
中缺少了“PromiseLike”。哦,这是一个多么愚蠢的错误。那一行应该是
从Promise(this.getToken())返回。管道
(注意
getToken
之后的
()
)来实际调用该方法。@nishilbhaveoh是的!它工作起来很有魅力。非常感谢你,兄弟。这很好。谢谢你,我们必须这样做,才能将存储中的数据使用到存储范围之外。get()承诺。很高兴听到它帮助了@George。是的,有时候使用异步方法看起来有点棘手。
// -------------------------------------------------------------------------
// Please note that I'm using lettable/pipeable operators (RxJS > 5.5.x)
// https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md
// -------------------------------------------------------------------------

import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from "rxjs/Observable";
import { Storage } from '@ionic/storage';
import { Globals } from '../globals/globals';

// New imports!
import { fromPromise } from 'rxjs/observable/fromPromise';
import { mergeMap } from 'rxjs/operators/mergeMap';

@Injectable()
export class Interceptor implements HttpInterceptor {

  constructor(private storage: Storage, private global: Globals){ }

  getToken(): Promise<any> {
    return this.storage.get('token');
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return fromPromise(this.getToken()).pipe(
        mergeMap(token => {

            // Use the token in the request
            req = req.clone({
                setHeaders: {
                    'Token': token,
                    'Version': this.global.version,
                }
            });

            // Handle the request
            return next.handle(req);
        }));
  }
}