处理 Angular 中的两个 URL (矩阵 && 查询)参数 4+

Handle both URL (matrix && query) parameters in Angular 4+

目前我们在我的 angular 4+ 应用程序中使用矩阵参数。 Google Analytics 在使用 ; 读取 URL 时出现问题,因此我们决定将其更改为查询参数。然而,旧符号(矩阵)必须可访问并重定向到新符号并将此类事件保存到数据库中。

我看到三种可能的解决方案:

  1. 使用自定义 URL serializer/parser 将使用正则表达式将矩阵转换为查询,保存到数据库并进行重定向
  2. 使用某种具有相同功能的路由守卫
  3. 使用专用组件来处理此功能

虽然第三种方式肯定是最后的选择,但我很难预测剩下的两种方式中哪一种会更好。

我会同时使用第一个和第三个解决方案。

我要使用的组件是 AppComponent,因为它是您应用程序中的最高组件。

然后,我将解析URL,检测它是否是矩阵表示法,如果是,则将其转换为查询参数表示法。

然后,我会使用查询参数符号将用户重定向到他要求的页面。

我的解决方案已通过所有测试,所以这里是

customUrlSerializer:

parse(url: any): UrlTree {
    const dus = new DefaultUrlSerializer();
    const splittedUrl = url.replace(/%3D/g, '=').split(/(;[\w\d-]*=[\w\d-]*)/g);

    const matrixParams = this.extractMatrixParams(splittedUrl);
    const queryParams = this.extractQueryParams(url);

    if (matrixParams) {
      this.saveOldUrlIncident(url);
    }

    const newUrl = this.buildNewString(splittedUrl, matrixParams, queryParams);
    return dus.parse(newUrl);
  }

  serialize(tree: UrlTree): any {
    const dus = new DefaultUrlSerializer(),
      path = dus.serialize(tree);
    return path.replace(/%3D/g, '=');
  }

  private extractMatrixParams(splittedUrl: string[]): string {
    return splittedUrl
      .filter(el => el.startsWith(';'))
      .reduce((a, b) => (a = a + b.substr(1) + '&', a), '')
      .slice(0, -1);
  }

  private extractQueryParams(url: string): string {
    return url.lastIndexOf('?') > -1 ? url.substr(url.lastIndexOf('?') + 1, url.length - 1) : '';
  }

  private buildNewString(splittedUrl: string[], matrixParams: string, queryParams: string): string {
    let newUrl = splittedUrl.reduce((a, b) => {
      if (b && !b.startsWith(';')) {
        if (b.indexOf('?')) {
          a = a + b.split('?')[0];
        } else {
          a = a + b;
        }
      }
      return a;
    }, '');

    if (matrixParams || queryParams) {
      newUrl = newUrl + '?';
    }
    if (matrixParams) {
      newUrl = newUrl + matrixParams;
    }
    if (queryParams) {
      newUrl = newUrl + (matrixParams ? '&' : '') + queryParams;
    }

    return newUrl;
  }

并且在 app.module 中,在提供者中添加: {provide: UrlSerializer, useClass: CustomUrlSerializer},