How to pass a param to HttpInterceptor?

前端 未结 4 2121
别跟我提以往
别跟我提以往 2020-12-15 04:11

I am using Angular 4.3.1 and HttpClient. There is an HttpInterceptor to set some headers.

In some http get requests I need to set a different header. Is there anywa

4条回答
  •  失恋的感觉
    2020-12-15 04:21

    Currently, Angular does not support passing "interceptor config/metadata" via the HttpRequest object (it has been an open issue for quite some time).

    As a possible workaround, we can define a new MyHttpParams class which extends Angular's HttpParams, adding a new interceptorMetadata property.

    Note that MyHttpParams must override the append, set and delete methods so that they return MyHttpParams instead of Angular's HttpParams. If we don't do this, our interceptorMetadata will be "dropped" when those methods are invoked (e.g. if an interceptor adds some HTTP param, the next interceptors will not get the interceptorMetadata).

    import {HttpParams} from '@angular/common/http';
    
    export interface InterceptorMetadata {
        readonly customParam1: string;
        readonly customParam2: number;
        // etc.
    }
    
    export interface MyHttpParamsConfig {
        interceptorMetadata: Partial;
        params: string | Record; // the actual params which will be included in the real request
    }
    
    export class MyHttpParams extends HttpParams {
        public readonly interceptorMetadata: Partial;
    
        constructor({params, interceptorMetadata}: Partial = {}) {
            if(typeof params === 'string') {
                super({fromString: params});
            }
            else if(typeof params === 'object') {
                super({fromObject: params});
            }
            else {
                super();
            }
    
            this.interceptorMetadata = interceptorMetadata;
        }
    
        // orverrides HttpParams.append
        append(param: string, value: string): MyHttpParams {
            const updatedHttpParams = super.append(param, value);
            return new MyHttpParams({
                interceptorMetadata: this.interceptorMetadata,
                params: updatedHttpParams.toString()
            });
        }
    
        // orverrides HttpParams.set
        set(param: string, value: string): MyHttpParams {
            const updatedHttpParams = super.set(param, value);
            return new MyHttpParams({
                interceptorMetadata: this.interceptorMetadata,
                params: updatedHttpParams.toString()
            });
        }
    
        // orverrides HttpParams.delete
        delete(param: string, value?: string): MyHttpParams {
            const updatedHttpParams = super.delete(param, value);
            return new MyHttpParams({
                interceptorMetadata: this.interceptorMetadata,
                params: updatedHttpParams.toString()
            });
        }
    }
    

    Then for example when calling HttpClient.get() we can pass an instance of our extended MyHttpParams:

    const myHttpParams = new MyHttpParams({
        interceptorMetadata: {
            customParam1: 'test', // this will NOT be part of the final request
        },
        params: 'someActualUrlQueryString=someValue' // this will be part of the final request
    });
    
    httpClient.get(myUrl, {params: myHttpParams})
    

    Finally, in our interceptor we can use interceptorMetadata:

    intercept(req: HttpRequest, next: HttpHandler): Observable> {
        const {params} = req;
        if(params instanceof MyHttpParams) {
            if (params.interceptorMetadata && params.interceptorMetadata.customParam1 === 'test') { 
                // do something
            }
        }
        // ...
    }
    

    Thanks to JWess for the original answer which this is based on (it was just missing the append, set and delete overrides)

提交回复
热议问题