router
router copied to clipboard
Route parameters containing forward slashes are not correctly encoded.
I'm submitting a bug
- Library Version: 1.6.3
Please tell us about your environment:
-
Operating System: Windows 10
-
Node Version: v10.13.0
-
NPM Version: 6.6.0
-
JSPM OR Webpack AND Version webpack 4.29.0
-
Browser: all
-
Language: TypeScript
Current behavior:
Route parameters containing forward slashes are not correctly encoded.
say this route is configured:
{ route: 'detail/:component', name: 'coded', moduleId: PLATFORM.moduleName('./coded/coded') }
navigating to the route by using:
this.router.navigateToRoute('details',{component:'some/thing'});
in the module after navigation:
activate(params:{component:string}){
//params.component is set to 'some'
}
What is the expected behavior?
in the module after navigation:
activate(params:{component:string}){
//params.component should be set to 'some/thing'
}
internally the router is using encodeURI()
which doesn't properly escape everything:
encodeURI
escapes all characters except: A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
It should probably use encodeURIComponent()
which properly encodes the fragments. This is a significant change to the behaviour of the router and might affect existing applications
I'd like to point out that this is a serious problem. Consider a use case where I want to send %/
as a route parameter:
- I have to escape it first by using
encodeURIComponent()
, because I can't put%
directly into a URL and/
would mess up the route parameters' contents. - After escaping, I get the encoded string
%25%2F
as expected and pass it along tonavigateToRoute()
. - When I want to access the route parameter in the
activate()
method, for example, the router has already done some decoding (presumably usingencodeURI()
) and all I get is%%2F
. - ????
- How am I supposed to decode only the
/
(as%2F
) and not%
?
EDIT: if I do encodeURIComponent(encodeURI("%/"))
in the first step, then I'll get %25%2F
in the third step as expected. Messing with route parameters without clearly stating it anywhere is not okay, and neither is using double-encoding to bypass this issue.
@hankur I think you can encode/decode your route parameters with base64 strings. So it may look like this:
- escape it first by using
btoa(...)
- ...
- When I want to access the route parameter in the activate() method, for example, the router has already done some decoding (presumably using encodeURI()) and decode it using
atob(...)
.
Can you try this?
@bigopon I guess this would work, but it would render the URL unreadable by us humans. Simple encodeURIComponent()
would only encode the special symbols, but text would still be understandable, which I'd prefer.