Interceptor Angular 4.3 - 在克隆的请求上设置多个标头

39r*_*9ro 22 header interceptor angular

我刚刚注意到新Interceptor中不再支持可能在先前的HTTP RequestsOption中使用的Header对象.

这是新的拦截器逻辑:

// Get the auth header from the service.
const authHeader = this.auth.getAuthorizationHeader();
// Clone the request to add the new header.
const authReq = req.clone({headers: req.headers.set('Authorization', authHeader)});
Run Code Online (Sandbox Code Playgroud)

我现在有两种方法可以在此请求中添加标题:

例:

headers?: HttpHeaders;

    headers: req.headers.set('token1', 'asd')
Run Code Online (Sandbox Code Playgroud)
setHeaders?: {
   [name: string]: string | string[];
};

    setHeaders: {
             'token1': 'asd',
             'token2': 'lol'
    }
Run Code Online (Sandbox Code Playgroud)

如何在此请求中有条件地添加多个标头?与我以前使用Header对象相同:

 myLovellyHeaders(headers: Headers) {
    headers.set('token1', 'asd');
    headers.set('token2', 'lol');
     if (localStorage.getItem('token1')) {
     headers.set('token3', 'gosh');
     }
    }
    const headers = new Headers();
    this.myLovellyHeaders(headers);
Run Code Online (Sandbox Code Playgroud)

non*_*4me 16

Angular 4.3+

在Interceptor中设置多个标题:

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

import {environment} from '../../../../environments/environment';

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

    const headers = new HttpHeaders({
      'Authorization': 'token 123',
      'WEB-API-key': environment.webApiKey,
      'Content-Type': 'application/json'
    });


    const cloneReq = req.clone({headers});

    return next.handle(cloneReq);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 你好,non4me,使用“req.clone({headers})”会错过原始标头吗? (2认同)

Max*_*kyi 11

新的HTTP客户端使用不可变的头对象.您需要存储对前一个标头的引用以改变对象:

 myLovellyHeaders(headers: Headers) {
     let p = headers.set('token1', 'asd');   
     p = p.set('token2', 'lol');
     if (localStorage.getItem('token1')) {
        p = p.set('token3', 'gosh');
     }
Run Code Online (Sandbox Code Playgroud)

请参阅为什么HttpParams在角度4.3中的多行中不起作用,以了解为什么需要存储对返回值的引用.

标题也是一样的:

export class HttpHeaders {
  ...
  set(name: string, value: string|string[]): HttpHeaders {
    return this.clone({name, value, op: 's'});
  }

  private clone(update: Update): HttpHeaders {
    const clone = new HttpHeaders();
    clone.lazyInit =
        (!!this.lazyInit && this.lazyInit instanceof HttpHeaders) ? this.lazyInit : this;
    clone.lazyUpdate = (this.lazyUpdate || []).concat([update]);
    return clone;
  }
Run Code Online (Sandbox Code Playgroud)

要了解有关拦截器背后的力学的更多信息,请阅读:


Ena*_*yat 10

我的代码使用以下方法添加新标头以用新值替换以前的值:

headers: req.headers.set('token1', 'asd')
.set('content_type', 'asd')
.set('accept', 'asd')
Run Code Online (Sandbox Code Playgroud)

  • .set() 不会附加标头,它会添加新标头来替换任何出现的标头。 (2认同)

Ale*_*lex 6

要附加到已克隆请求的现有标头(例如HTTP Interceptor中的标头),下面的代码可以工作(使用Angular 5.x)。在以下情况下,它将附加到现有头(在我的情况下包括Angular自动包含的XSRF-TOKEN cookie)中,并在sessionStorage中存储一个JWT授权令牌:

export class TokenInterceptor implements HttpInterceptor {

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

        let headers = request.headers
            .set('Content-Type', 'application/json')
            .set('Authorization', `Bearer ${sessionStorage.getItem('authToken')}`);

        const cloneReq = request.clone({ headers });

        return next.handle(cloneReq);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 由于我使用 Angular 9,请确保采用这种格式 `const cloneReq = request.clone({ headers : headers });` (3认同)