【问题标题】:Angular HttpInterceptor RangeError: Maximum call stack size exceededAngular HttpInterceptor RangeError:超出最大调用堆栈大小
【发布时间】:2021-03-07 01:24:13
【问题描述】:

我在短时间内多次调用 HttpInterceptor 时遇到问题,导致错误:RangeError: Maximum call stack size exceeded。

我的 HttpInterceptor 正在拦截每个向标头添加不记名令牌的请求。第一次通过拦截器时,它将从身份验证服务器获取令牌,这会导致在短时间内对身份验证器进行许多 POST 调用。我猜这是当它在标头中没有承载令牌时,拦截器将使用 HttpClient 进行调用,从而使拦截器 再次 传递 true 并继续调用 GetAuthToken() 导致循环直到错误出现.

我试图忽略标头中带有标志的请求,但它仍然在循环。您对如何解决这个问题有什么建议吗?

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log('INTERCEPTOR');
    // We retrieve the token, if any
    const token = this.GetAuthToken();
    let newHeaders = req.headers;
    if (token) {
       // If we have a token, we append it to our new headers
       newHeaders = newHeaders.append('Authorization', "bearer " + token);
    }
    // Finally we have to clone our request with our new headers
    // This is required because HttpRequests are immutable
    const authReq = req.clone({headers: newHeaders});
    // Then we return an Observable that will run the request
    // or pass it to the next interceptor if any
    return next.handle(authReq);
  }

  GetAuthToken(): any{
    if (localStorage.getItem('access_token') != null){
        return localStorage.getItem('access_token');
      }
    let httpHeaders = new HttpHeaders({
       'Content-Type' : 'application/x-www-form-urlencoded'
    });
    let options = {
      headers: httpHeaders
    };
    let body = `grant_type=${this.grant_type}&client_id=${this.client_id}&username=${this.username}&password=${this.password}`
    this._http.post<AuthResponse>(this.url, body, options).subscribe(result => {
      localStorage.setItem('access_token', result.access_token);
      localStorage.setItem('refresh_token', result.refresh_token);
      return result.access_token;
    });
  }

【问题讨论】:

    标签: angular access-token angular-httpclient bearer-token angular-http-interceptors


    【解决方案1】:

    你的拦截器拦截所有,甚至你在 GetAuthToken 中的调用,你需要使用“if”来跳过来自 GetAuthToken 的调用

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if (req.body==`grant_type=${this.grant_type}&client_id=${this.client_id}&username=${this.username}&password=${this.password}`)
              return next.handle(req);
    
        ...rest of your code..
      }
    

    你也可以添加一个“傻瓜头”,就像它在this SO中显示的那样

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if (req.headers.get("skip")){
          const newHeader=req.headers.delete("skip");
          const newreq= req.clone({headers: newHeaders});
          return next.handle(newreq);
        }
        ...rest of your code..
      }
    

    在 GetAuthToken() 中

    GetAuthToken(){
       ...
       let options = {
          headers: httpHeaders.Add("skip",true)
        };
       ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-24
      • 2018-02-06
      • 1970-01-01
      • 2019-05-14
      • 2019-02-07
      • 2021-05-30
      相关资源
      最近更新 更多