【问题标题】:How to add multiple headers in Angular 5 HttpInterceptor如何在 Angular 5 HttpInterceptor 中添加多个标头
【发布时间】:2018-07-18 21:42:15
【问题描述】:

我正在尝试学习如何使用 HttpInterceptor 为应用程序对 API 执行的每个 HTTP 请求添加几个标头。我有这个拦截器:

import { Injectable } from '@angular/core';

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

import { Observable } from 'rxjs/Observable';


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

    const authReq = req.clone({
      headers: req.headers.set('Content-Type', 'application/json')
    });

    console.log('Intercepted HTTP call', authReq);

    return next.handle(authReq);
  }
}

除了'Content-Type' 标头之外,我还需要添加一个'Authorization',但我不知道怎么做(Angular HttpHeaders 的文档只是方法列表,没有任何解释)。

我该怎么做?谢谢!

【问题讨论】:

    标签: angular angular-http-interceptors angular-httpclient


    【解决方案1】:

    编辑:按照 cmets 中的建议,我统一了两个答案

    覆盖所有标题

    @Injectable()
    export class fwcAPIInterceptor implements HttpInterceptor {
      intercept (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
      const authReq = req.clone({
        headers: new HttpHeaders({
          'Content-Type':  'application/json',
          'Authorization': 'my-auth-token'
        })
      });
    
      console.log('Intercepted HTTP call', authReq);
    
      return next.handle(authReq);
    }
    

    在不覆盖的情况下添加更多标题(感谢 Ketan Patil - 请参阅此帖子中的答案)

    const authReq = req.clone({
        headers: req.headers.set('Content-Type', 'application/json')
            .set('header2', 'header 2 value')
            .set('header3', 'header 3 value')
    });
    

    【讨论】:

    • 如果你有多个拦截器怎么办?这会覆盖之前设置的那些标题,不是吗?
    • 如果您有多个用于 http 调用的拦截器,您应该重构您的逻辑:拥有一个用于处理标头或其他常见逻辑等的父类,但这是另一个未包含在此问题中的问题; )
    • @MarcScheib 检查我的答案。
    • 覆盖整个标题对象不是一个好习惯。任何看这里的人都应该检查下面的其他答案,因为他们有更好的解决方案。
    • 要在new Headers()...中包含原始标题,您只需在里面添加...req.headersnew HttpHeaders({ ...req.headers, 'Content-Type': 'application/json' })
    【解决方案2】:

    我尝试了以下使用拦截器发送自定义标头的方法。请查看链接stackBlitz

    请参考控制台截图browser console-request header

    并且在

    中添加了自定义标题

    access-control-request-headers:authkey,content-type,deviceid

    我希望将标头添加为标头的一部分,而不是在访问控制请求标头中。请在这方面给我建议

    【讨论】:

      【解决方案3】:
        const modifiedReq = req.clone({
            url: this.setUrl(req.url),
            headers: this.addExtraHeaders(req.headers)
          });
      

      以及方法:

      private addExtraHeaders(headers: HttpHeaders): HttpHeaders {
        headers = headers.append('myHeader', 'abcd');
        return headers;
      } 
      

      .append 方法创建一个新的 HttpHeaders 对象,添加 myHeader 并返回新对象。

      使用此解决方案意味着您还可以使用多个拦截器,因为您不会覆盖您的标头。

      【讨论】:

        【解决方案4】:

        由于set 方法每次都返回headers 对象,你可以这样做。这样,被截取的请求中的原始标头也将被保留。

        const authReq = req.clone({
            headers: req.headers.set('Content-Type', 'application/json')
            .set('header2', 'header 2 value')
            .set('header3', 'header 3 value')
        });
        

        【讨论】:

        • 这通常是您想要的方式。接受的答案将覆盖任何以前的标题,所以如果这是你想要做的,很好;但 OP 要求“添加”标题,而不是全部重置。
        • 这应该是公认的答案。如上所述,它将覆盖任何已设置的标头。我遇到了这个问题。这解决了它。
        • 这是正确的答案,它保留了现有的标题。
        • 这非常适合链接拦截器标头。优于公认答案的首选方法
        • 这是角度文档建议的正确方法。 angular.io/guide/http#adding-and-updating-headers
        【解决方案5】:

        如前所述 - 接受的方法会覆盖标题,为了添加它们,我喜欢来自 API documentation 的方法:

        const authReq = req.clone({ setHeaders: { Authorization: authToken } });
        

        【讨论】:

        • 这确实是最干净的方法。
        • 关键区别是 setHeaders 中的“设置”
        【解决方案6】:

        在你的拦截器文件中

        import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
        import {Injectable} from '@angular/core';
        import {Observable} from 'rxjs';
        @Injectable()
        export class fwcAPIInterceptor implements HttpInterceptor {
          intercept (req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        
          const auth = req.clone({
            headers: new HttpHeaders({
              'Content-Type':  'application/json',
              'Auth-Token': 'jwtToken'
            })
          });
        
        
        
          return next.handle(auth);
        }
        
        
        
         **in app module**
        
        import {HTTP_INTERCEPTORS} from '@angular/common/http';
        
        
        @NgModule({
          declarations: [
            AppComponent
          ],
          imports: [
            BrowserModule
          ],
          providers: [
            {provide: HTTP_INTERCEPTORS, useClass: CustomHttpInterceptorService, multi: true},
          ],
          bootstrap: [AppComponent]
        })
        

        【讨论】:

          【解决方案7】:
          @Injectable()
          export class fwcAPIInterceptor implements HttpInterceptor {
            intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
          
              let headers = new HttpHeaders();
              headers = headers.set('Content-Type', 'application/json');
              headers = headers.set('Authorization', 'my-auth-token');
          
              const authReq = req.clone({headers});
              console.log('Intercepted HTTP call', authReq);
          
              return next.handle(authReq);
            }
          }
          

          【讨论】:

            猜你喜欢
            • 2021-11-08
            • 2019-07-16
            • 1970-01-01
            • 1970-01-01
            • 2023-03-29
            • 1970-01-01
            • 1970-01-01
            • 2018-05-14
            相关资源
            最近更新 更多