处理 Angular 中的两个 URL (矩阵 && 查询)参数 4+
Handle both URL (matrix && query) parameters in Angular 4+
目前我们在我的 angular 4+ 应用程序中使用矩阵参数。 Google Analytics 在使用 ;
读取 URL 时出现问题,因此我们决定将其更改为查询参数。然而,旧符号(矩阵)必须可访问并重定向到新符号并将此类事件保存到数据库中。
我看到三种可能的解决方案:
- 使用自定义 URL serializer/parser 将使用正则表达式将矩阵转换为查询,保存到数据库并进行重定向
- 使用某种具有相同功能的路由守卫
- 使用专用组件来处理此功能
虽然第三种方式肯定是最后的选择,但我很难预测剩下的两种方式中哪一种会更好。
我会同时使用第一个和第三个解决方案。
我要使用的组件是 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},
目前我们在我的 angular 4+ 应用程序中使用矩阵参数。 Google Analytics 在使用 ;
读取 URL 时出现问题,因此我们决定将其更改为查询参数。然而,旧符号(矩阵)必须可访问并重定向到新符号并将此类事件保存到数据库中。
我看到三种可能的解决方案:
- 使用自定义 URL serializer/parser 将使用正则表达式将矩阵转换为查询,保存到数据库并进行重定向
- 使用某种具有相同功能的路由守卫
- 使用专用组件来处理此功能
虽然第三种方式肯定是最后的选择,但我很难预测剩下的两种方式中哪一种会更好。
我会同时使用第一个和第三个解决方案。
我要使用的组件是 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},