拦截器不拦截http请求(Angular 6)

Mik*_*123 13 angular

我正在为我的角度6项目添加一个拦截器.要调用我的API,我需要为所有调用添加一个承载令牌.不幸的是,似乎没有调用拦截器.我的代码:

import { Injectable } from "@angular/core";
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from "@angular/common/http";
import { Observable } from "rxjs";

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

    intercept(req: HttpRequest<any>,
              next: HttpHandler): Observable<HttpEvent<any>> {

        //Retrieve accesstoken from local storage
        const accessToken = localStorage.getItem("access_token");

        //Check if accesToken exists, else send request without bearer token
        if (accessToken) {
            const cloned = req.clone({
                headers: req.headers.set("Authorization",
                    "Bearer " + accessToken)
            });

            console.log('Token added to HTTP request');

            return next.handle(cloned);
        }
        else {
            //No token; proceed request without bearer token
            console.log('No token added to HTTP request');
            return next.handle(req);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有谁知道可能导致这个问题的原因是什么?提前致谢.

Pra*_*dey 25

在我的情况下,拦截器并没有参与服务调用,因为我HttpClientModule为不同的模块多次导入了。

后来我发现HttpClientModule只能导入一次。文档参考

希望这可以帮助!

  • 谢谢 !!连续两天试图解决这个问题...这是 HttpClientModule 的多次导入 (2认同)
  • 发现!确保您不会导入两次或多次。还要检查您的共享模块,以防您在应用程序模块中导入任何模块。至少这对我来说是个问题:) (2认同)

小智 13

你使用正确的方法来拦截.

对于使用拦截器的人,您需要进行2次修改:

拦截器在服务中

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse }
  from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';

@Injectable()
export class MyInterceptor implements HttpInterceptor {
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {

    return next.handle(req).do(evt => {
      if (evt instanceof HttpResponse) {
        console.log('---> status:', evt.status);
        console.log('---> filter:', req.params.get('filter'));
      }
    });

  }
}
Run Code Online (Sandbox Code Playgroud)

提供HTTP_INTERCEPTOR

import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
(...)
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: MyInterceptor, multi: true }
  ],
Run Code Online (Sandbox Code Playgroud)

阅读本文了解更多详情.这是相当不错

  • 请记住,rxjs 已经发生了很大变化。do 运算符现在称为 tap ,需要在 pipeline() 中使用 https://www.academind.com/learn/javascript/rxjs-6-what-c​​hanged/ (3认同)

小智 9

如果您有一个模块的提供者数组,那么您也必须为该模块定义 HTTP_INTERCEPTORS,然后只有它才会拦截该模块下的请求。

例如:

providers: [ 
// singleton services
PasswordVerifyService,
{ provide: HTTP_INTERCEPTORS, useClass: AppInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptorService, multi: true }
]
Run Code Online (Sandbox Code Playgroud)


and*_*mel 5

我的独立组件有完全相同的行为(拦截器不拦截我的 http 请求)。

如果您使用独立组件而不是在模块中导入 HttpClientModule,请注意,您必须添加 HttpClientModulewithInterceptorsFromDi()才能provideHttpClient(...)使拦截器工作!或者通过withInterceptors.

有关更多详细信息,请参阅此 SO 帖子