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

时间:2018-06-14 14:50:05

标签: angular

我正在为我的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);
        }
    }
}

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

5 个答案:

答案 0 :(得分:11)

您使用正确的方法进行拦截。

对于使用拦截器的人,您需要进行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'));
      }
    });

  }
}

提供HTTP_INTERCEPTOR

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

Read this article for more details。它很不错

答案 1 :(得分:3)

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

后来我发现HttpClientModule只能被导入一次。 Doc ref

希望这会有所帮助!

答案 2 :(得分:1)

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

例如:

providers: [ 
// singleton services
PasswordVerifyService,
{ provide: HTTP_INTERCEPTORS, useClass: AppInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptorService, multi: true }
]

答案 3 :(得分:1)

就我而言,我必须将两个HTTP_INTERCEPTORS, HttpClientModule导入同一模块中。

答案 4 :(得分:0)

就我而言,我有一个像这样的发布方法:

this.http.post<any>(this.authUrl, JSON.stringify({username: username, password: password})).pipe(
      map((response: any) => {
            let token: any = response.token;
            if (token) {
                localStorage.setItem('currentUser', 'value' }));                
                return response; 
            } else {
                return null;
            }
        }),
        catchError((error:any) => {return observableThrowError(error.json().error || 'Server error')})
      );

因为map方法可以返回null,所以拦截器停止拦截此post方法调用发出的请求。不要问我为什么会这样,但是一旦我将null替换为response,一切就会重新开始。