Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度2+;HttpIntercept:在返回intercept函数之前,等待来自服务器的令牌_Angular_Rxjs - Fatal编程技术网

Angular 角度2+;HttpIntercept:在返回intercept函数之前,等待来自服务器的令牌

Angular 角度2+;HttpIntercept:在返回intercept函数之前,等待来自服务器的令牌,angular,rxjs,Angular,Rxjs,我知道这个问题以前是以一种方式/形式/形式解决的,但我已经复习了我能找到的所有问题和答案,仍然不知道如何解决这个问题 HttpIntercept.intercept必须返回next.handle(请求)。但是,我需要它等待(我知道“wait”在前端是一个肮脏的词)承载令牌从服务器返回,然后才能返回。我一生都找不到一个模式来实现这一点。在我们到达服务器获取承载令牌之前,拦截函数无法返回 如果已经回答了这个问题,我很抱歉,请为我提供相应答案的链接 非工作示例(函数在附加令牌之前返回): 导出类令牌拦

我知道这个问题以前是以一种方式/形式/形式解决的,但我已经复习了我能找到的所有问题和答案,仍然不知道如何解决这个问题

HttpIntercept.intercept必须返回next.handle(请求)。但是,我需要它等待(我知道“wait”在前端是一个肮脏的词)承载令牌从服务器返回,然后才能返回。我一生都找不到一个模式来实现这一点。在我们到达服务器获取承载令牌之前,拦截函数无法返回

如果已经回答了这个问题,我很抱歉,请为我提供相应答案的链接

非工作示例(函数在附加令牌之前返回):

导出类令牌拦截器实现HttpInterceptor{
构造函数(私有身份验证:AuthenticationService){}
拦截(请求:HttpRequest,下一步:HttpHandler):可观察{
let令牌:字符串;
this.auth.getToken().subscribe(响应=>{
令牌=响应['access_token'];
request=request.clone({
集合标题:{
授权:`Bearer${token}`
}
});
});
下一步返回。处理(请求);
}
}

当您的请求是异步的时,正在同步调用您的处理程序

由于您需要返回一个可观察值,请查看rxjs中的
flatMap
/
switchMap
操作符,它看起来像:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let token: string;
    return this.auth.getToken().flatMap(response => {
      token = response['access_token'];
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
      return next.handle(request);
    });
}
export class TokenInterceptor implements HttpInterceptor {
  constructor(private auth: AuthenticationService) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return this.auth.getToken()
        .map(response => request.clone({setHeaders: {Authorization: `Bearer ${response['access_token']}`}}))
        .switchMap(request => next.handle(request));
  }
}
intercept(请求:HttpRequest,下一步:HttpHandler):可观察{
let令牌:字符串;
返回此.auth.getToken().flatMap(响应=>{
令牌=响应['access_token'];
request=request.clone({
集合标题:{
授权:`Bearer${token}`
}
});
下一步返回。处理(请求);
});
}

使用
开关映射
从另一个
可观察
返回
可观察

export class TokenInterceptor implements HttpInterceptor {
  constructor(private auth: AuthenticationService) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let token: string;
    return this.auth.getToken().switchMap(response => {
      token = response['access_token'];
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });

       return next.handle(request);
    });
  }
}
导出类令牌拦截器实现HttpInterceptor{
构造函数(私有身份验证:AuthenticationService){}
拦截(请求:HttpRequest,下一步:HttpHandler):可观察{
let令牌:字符串;
返回此.auth.getToken().switchMap(响应=>{
令牌=响应['access_token'];
request=request.clone({
集合标题:{
授权:`Bearer${token}`
}
});
下一步返回。处理(请求);
});
}
}

尝试返回可观察的已完成函数:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let token: string;
    this.auth.getToken().subscribe(response => {
      token = response['access_token'];
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
    },
    err => { console.log(err) },
    () => return next.handle(request) // this is called after the completion of observable
    );

  }
}
intercept(请求:HttpRequest,下一步:HttpHandler):可观察{
let令牌:字符串;
this.auth.getToken().subscribe(响应=>{
令牌=响应['access_token'];
request=request.clone({
集合标题:{
授权:`Bearer${token}`
}
});
},
err=>{console.log(err)},
()=>return next.handle(request)//在observable完成后调用
);
}
}

我能想到类似这样的事情:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let token: string;
    return this.auth.getToken().flatMap(response => {
      token = response['access_token'];
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
      return next.handle(request);
    });
}
export class TokenInterceptor implements HttpInterceptor {
  constructor(private auth: AuthenticationService) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return this.auth.getToken()
        .map(response => request.clone({setHeaders: {Authorization: `Bearer ${response['access_token']}`}}))
        .switchMap(request => next.handle(request));
  }
}
导出类令牌拦截器实现HttpInterceptor{
构造函数(私有身份验证:AuthenticationService){}
拦截(请求:HttpRequest,下一步:HttpHandler):可观察{
返回this.auth.getToken()
.map(response=>request.clone({setHeaders:{Authorization:`Bearer${response['access\u token']}}}}))
.switchMap(请求=>next.handle(请求));
}
}


虽然我不确定它是否会起作用。

如果你发布了你的代码,那会很有帮助。更不用说帖子上说代币来自哪里了server@VincentNguyen令牌是由服务器生成的。请尝试将返回放在subscribe的第三个回调参数中。好的,我已经考虑过这一点,但是要实现HttpInterceptor接口,intercept函数必须返回一个可观察值。我应该只返回一个“虚拟”可观察对象吗?这会导致请求在拦截器完成其工作之前发出吗?是的,我完全没有意识到这似乎是一项非常常见的任务(从服务器获取令牌并将其附加到API调用中)。我感到惊讶的是,我很难解决或找到一个现有模式。@SeanIvins我在应用程序中所做的是先获取令牌并将其存储在localstorage中……但让我试着为您编写一个答案,让您尝试编译它,因为该方法没有返回anything@J.Pichardo陛下not SURE return next.handle只返回匿名函数,而不是截取函数那么当令牌过期时你该怎么办?这是一个更清晰的答案。这样你就可以去掉本地
令牌
变量This.auth.getToken()需要将一个可观察的(httpClient.post)not
开关映射
返回到
next.handle(请求)
应将可观察的类型更改为
可观察的
,至少按照我的想法。返回下一步。handle(请求)返回switchMap中的函数,而不是截取函数yes,但
返回此函数。auth.getToken().switchMap()
=>这是一个
可观察的
很抱歉错过了它。好的,那么switchMap将返回它的参数返回的值?即将继续模拟实现。我甚至还没有完成这项工作来测试它。
switchMap
将返回
下一步。句柄(请求)
,这意味着
可观察的