Angular HttpParams 有没有办法在生成具有相同键的查询参数时将方括号添加到序列化的查询参数中?

Angular HttpParams is there a way to add square brackets to serialized query params when generating query params with the same key?

当使用具有相同键但多个值的多个查询参数查询我的 api 时,除非在每个键中添加方括号,否则它无法正确解释请求。让我举个例子:

    let params = new HttpParams();

    params = params.append('color', 'blue');
    params = params.append('color', 'red');

    console.log(params.toString()) // color=blue&color=red 
    // Would prefer color[]=blue&color[]=red

有什么方法可以实现这个功能吗?

我通过编写自己的拦截器并使用另一个库生成查询字符串来解决这个问题。请看下面:

安装这个库:

$ npm i query-string --save

添加这个拦截器:

import {
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpParams,
  HttpRequest,
} from '@angular/common/http';
import { Observable } from 'rxjs';
import * as querystring from 'query-string';

@Injectable()
export class QueryParamInterceptor implements HttpInterceptor {

  constructor() {}

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

    if (!request.params.keys().length || request.method !== 'GET') {
      return next.handle(request);
    }

    let { params } = request;

    let queryParams = this.createQueryParams(params);

    let queryString = querystring.stringify(queryParams, { arrayFormat: 'bracket' });

    let urlWithParams = request.urlWithParams.replace(request.params.toString(), queryString);

    request = request.clone({
      url: urlWithParams,
      params: new HttpParams(),
    });

    return next.handle(request);
  }

  private createQueryParams(params: HttpParams): { [key: string]: string } {
    let queryParams = {};

    for (let key of params.keys()) {
      let values = params.getAll(key);

      if (!values) {
        continue;
      }

      if (values.length === 1) {
        queryParams[key] = values[0];

        continue;
      }

      queryParams[key] = values;
    }

    return queryParams;
  }
}

您可以重写 angulars 的 HttpParameterCodec 以不对方括号进行编码:

export class MyCustomHttpUrlEncodingCodec extends HttpUrlEncodingCodec {
    encodeKey(k: string): string {
        return super.encodeKey(k)
            .replace(new RegExp("%5B", "g"), "[")
            .replace(new RegExp("%5D", "g"), "]");
    }
}

我在这里更详细地描述了我的解决方案:http://www.moritz-benzenhoefer.com/angular-http-requests-use-square-brackets-in-httpparams-as-parameter-key-name/