typescript 如何排除某些服务,如登录、从拦截器 Angular 5 注册、HttpClient

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49746548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:20:50  来源:igfitidea点击:

How to exclude some services like login, register from interceptor Angular 5, HttpClient

angulartypescriptinterceptorangular-httpclient

提问by Haneep CR

i wanted to exclude some services using interceptor.

我想使用拦截器排除一些服务。

app.module.js

app.module.js

providers: [
    UserService,
    RolesService,
    {
        provide: HTTP_INTERCEPTORS,
        useClass: TokenInterceptor,
        multi: true
      },
],

Login.service.ts

登录.service.ts

return this.httpClient.post(this.appUrl + '/oauth/token', body.toString(), { headers, observe: 'response' })
.map((res: Response) => {
  const response = res.body;
  this.storeToken(response);
  return response;
})
.catch((error: any) => {
  ErrorLogService.logError(error);
  return Observable.throw(new Error(error.status));
  });
}

采纳答案by Fussel

To give this an answer not only in comments as requested ;-)

不仅要根据要求在评论中给出答案;-)

To exclude some services (or even the same services used in different components) from an interceptor it's best to split your application into modules and provide the interceptor only in modules where it's needed. For example after logging in or inside of an admin area.

要从拦截器中排除某些服务(甚至是不同组件中使用的相同服务),最好将您的应用程序拆分为多个模块,并仅在需要的模块中提供拦截器。例如,在登录后或在管理区域内。

The interceptor may be even provided for single components using the @Componentdeclaration's providersproperty.

甚至可以使用@Component声明的providers属性为单个组件提供拦截器。

回答by DragoRaptor

Although #Fussel's answer (above) works, it's often not good practice to include the interceptor service in every component module. It's counter intuitive and counter productive. We want the interceptor in one place and work for all http requests. One way is to exclude the header binding in the intercept() function based on the url.

尽管#Fussel 的答案(以上)有效,但在每个组件模块中包含拦截器服务通常不是一个好习惯。这是违反直觉和适得其反的。我们希望拦截器在一个地方并为所有 http 请求工作。一种方法是根据url在intercept()函数中排除header绑定。

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const re = /login/gi;
// Exclude interceptor for login request:
if (req.url.search(re) === -1 ) {
  req = req.clone({
    setHeaders: {
      Authorization: `Bearer ${localStorage.getItem('authToken')}`
    }
  });
}
return next.handle(req);

}

}

回答by Manuel Ortiz

I had to solve this same. The division into modules is very expensive for me. And the #DragoRaptor solution is not suitable when you have several points where you need to "jump" the interceptor

我不得不解决这个问题。划分模块对我来说非常昂贵。当您有几个需要“跳”拦截器的点时,#DragoRaptor 解决方案不适合

My solution is unorthodox, but maybe it will serve someone else.

我的解决方案是非正统的,但也许它会为其他人服务。

It simply consists of:

它简单地包括:

  1. Include one more parameter in the request
  2. Check for this parameter in the interceptor
  3. Remove the parameter
  1. 在请求中再包含一个参数
  2. 在拦截器中检查这个参数
  3. 移除参数

Invocation example

调用示例

    public searchPersons(term: string): Observable<any> {
       return this.http.get('person/', { params: { dni: term, spinner: 'no' } });
    }

Interceptor example

拦截器示例

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

// check if you have the parameter 'spinner'
    const spinner = request.params.get('spinner');
    if (spinner && spinner === 'no') {

// remove parameter
      request.params.delete('spinner');

// jump the interceptor
      return next.handle(request);
    }

// Execute interceptor

  }
}

回答by Pran R.V

You can use HttpBackend for this. Example is given below

您可以为此使用 HttpBackend。示例如下

import { Injectable } from '@angular/core';
import { HttpClient, HttpBackend } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class NoheaderService {

 private httpClient: HttpClient;
  constructor( handler: HttpBackend) { 
     this.httpClient = new HttpClient(handler);
     }

   fetchInsta(username) {
      return new Promise((resolve, reject) => {
         this.httpClient.get(`https://www.instagram.com/${username}/?__a=1`)
          .subscribe((response: any) => {
           resolve(response);
             },reject);
               })
              }
          }

回答by Dejan Jovancevic

I had the similar problem. Once implemented interceptor hunt all http requests anyway. It was in my code about if i have, or not access token. If I haven't than interceptors token parametar has to be set to ""(empty string). Than everything goes. In the interceptor fn code it seems like this:

我有类似的问题。一旦实现拦截器,无论如何都会追捕所有 http 请求。在我的代码中是关于我是否有访问令牌。如果我还没有拦截器令牌参数必须设置为“”(空字符串)。比一切都好。在拦截器 fn 代码中,它看起来像这样:

       intercept(
          request: HttpRequest<any>,
          next: HttpHandler**strong text**
       ): Observable<HttpEvent<any>> {

        //how to update the request Parameters
        **let token : string;
        let currentUser : any = JSON.parse(localStorage.getItem('currentUser'));
        if (currentUser){
            token = currentUser.access_token;
        }else{token = ""}**

        console.log("Token dobavljen sa localStorage.getItem:   ", token);
        if (token) {
            request = request.clone({ headers: request.headers.set('Authorization', 'Bearer ' + token) });
        }

        if (!request.headers.has('Content-Type')) {
            request = request.clone({ headers: request.headers.set('Content-Type', 'application/json') });
        }

        request = request.clone({ headers: request.headers.set('Accept', 'application/json') });

        //logging the updated Parameters to browser's console
        console.log("Before making api call : ", token);

        return next.handle(request).pipe(
            tap(
                event => {
                    //logging the http response to browser's console in case of a success
                    if (event instanceof HttpResponse) {
                    console.log("api call success :", event);
                    }
                },
                error => {
                    //logging the http response to browser's console in case of a failuer
                    if (event instanceof HttpResponse) {
                    console.log("api call error :", event);
                    }
                }
            )
        );
    //}
}