fix(router): encode/decode params and path segments
This commit is contained in:
parent
f7a0e9ecb6
commit
46e105f3ab
|
@ -183,7 +183,7 @@ export class DefaultUrlSerializer implements UrlSerializer {
|
||||||
serialize(tree: UrlTree): string {
|
serialize(tree: UrlTree): string {
|
||||||
const segment = `/${serializeSegment(tree.root, true)}`;
|
const segment = `/${serializeSegment(tree.root, true)}`;
|
||||||
const query = serializeQueryParams(tree.queryParams);
|
const query = serializeQueryParams(tree.queryParams);
|
||||||
const fragment = tree.fragment !== null ? `#${tree.fragment}` : '';
|
const fragment = tree.fragment !== null ? `#${encodeURIComponent(tree.fragment)}` : '';
|
||||||
return `${segment}${query}${fragment}`;
|
return `${segment}${query}${fragment}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,15 +223,18 @@ function serializeSegment(segment: UrlSegment, root: boolean): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function serializePath(path: UrlPathWithParams): string {
|
export function serializePath(path: UrlPathWithParams): string {
|
||||||
return `${path.path}${serializeParams(path.parameters)}`;
|
return `${encodeURIComponent(path.path)}${serializeParams(path.parameters)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function serializeParams(params: {[key: string]: string}): string {
|
function serializeParams(params: {[key: string]: string}): string {
|
||||||
return pairs(params).map(p => `;${p.first}=${p.second}`).join('');
|
return pairs(params)
|
||||||
|
.map(p => `;${encodeURIComponent(p.first)}=${encodeURIComponent(p.second)}`)
|
||||||
|
.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function serializeQueryParams(params: {[key: string]: string}): string {
|
function serializeQueryParams(params: {[key: string]: string}): string {
|
||||||
const strs = pairs(params).map(p => `${p.first}=${p.second}`);
|
const strs =
|
||||||
|
pairs(params).map(p => `${encodeURIComponent(p.first)}=${encodeURIComponent(p.second)}`);
|
||||||
return strs.length > 0 ? `?${strs.join("&")}` : '';
|
return strs.length > 0 ? `?${strs.join("&")}` : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +338,7 @@ class UrlParser {
|
||||||
if (this.peekStartsWith(';')) {
|
if (this.peekStartsWith(';')) {
|
||||||
matrixParams = this.parseMatrixParams();
|
matrixParams = this.parseMatrixParams();
|
||||||
}
|
}
|
||||||
return new UrlPathWithParams(path, matrixParams);
|
return new UrlPathWithParams(decodeURIComponent(path), matrixParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
parseQueryParams(): {[key: string]: any} {
|
parseQueryParams(): {[key: string]: any} {
|
||||||
|
@ -353,7 +356,7 @@ class UrlParser {
|
||||||
|
|
||||||
parseFragment(): string {
|
parseFragment(): string {
|
||||||
if (this.peekStartsWith('#')) {
|
if (this.peekStartsWith('#')) {
|
||||||
return this.remaining.substring(1);
|
return decodeURIComponent(this.remaining.substring(1));
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -384,7 +387,7 @@ class UrlParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
params[key] = value;
|
params[decodeURIComponent(key)] = decodeURIComponent(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
parseQueryParam(params: {[key: string]: any}): void {
|
parseQueryParam(params: {[key: string]: any}): void {
|
||||||
|
@ -402,7 +405,7 @@ class UrlParser {
|
||||||
this.capture(value);
|
this.capture(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
params[key] = value;
|
params[decodeURIComponent(key)] = decodeURIComponent(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
parseParens(allowPrimary: boolean): {[key: string]: UrlSegment} {
|
parseParens(allowPrimary: boolean): {[key: string]: UrlSegment} {
|
||||||
|
|
|
@ -134,6 +134,36 @@ describe('url serializer', () => {
|
||||||
expect(tree.fragment).toEqual('');
|
expect(tree.fragment).toEqual('');
|
||||||
expect(url.serialize(tree)).toEqual('/one#');
|
expect(url.serialize(tree)).toEqual('/one#');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('encoding/decoding', () => {
|
||||||
|
it('should encode/decode path segments and parameters', () => {
|
||||||
|
const u =
|
||||||
|
`/${encodeURIComponent("one two")};${encodeURIComponent("p 1")}=${encodeURIComponent("v 1")};${encodeURIComponent("p 2")}=${encodeURIComponent("v 2")}`;
|
||||||
|
const tree = url.parse(u);
|
||||||
|
|
||||||
|
expect(tree.root.children[PRIMARY_OUTLET].pathsWithParams[0].path).toEqual('one two');
|
||||||
|
expect(tree.root.children[PRIMARY_OUTLET].pathsWithParams[0].parameters)
|
||||||
|
.toEqual({['p 1']: 'v 1', ['p 2']: 'v 2'});
|
||||||
|
expect(url.serialize(tree)).toEqual(u);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should encode/decode query params', () => {
|
||||||
|
const u =
|
||||||
|
`/one?${encodeURIComponent("p 1")}=${encodeURIComponent("v 1")}&${encodeURIComponent("p 2")}=${encodeURIComponent("v 2")}`;
|
||||||
|
const tree = url.parse(u);
|
||||||
|
|
||||||
|
expect(tree.queryParams).toEqual({['p 1']: 'v 1', ['p 2']: 'v 2'});
|
||||||
|
expect(url.serialize(tree)).toEqual(u);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should encode/decode fragment', () => {
|
||||||
|
const u = `/one#${encodeURIComponent("one two")}`;
|
||||||
|
const tree = url.parse(u);
|
||||||
|
|
||||||
|
expect(tree.fragment).toEqual('one two');
|
||||||
|
expect(url.serialize(tree)).toEqual(u);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function expectSegment(segment: UrlSegment, expected: string, hasChildren: boolean = false): void {
|
function expectSegment(segment: UrlSegment, expected: string, hasChildren: boolean = false): void {
|
||||||
|
|
Loading…
Reference in New Issue