Description
UI-Router has had troubles encoding slashes in path parameters for quite a while now.
example:
Given: a url with parameters: /path/:param1/:param2
If: param1
is foo/bar
and param2
is baz/qux
The browser URL should be: /path/foo%2Fbar/baz%2Fqux
We've gone through a few iterations to encode those slashes, including attempting double encoding (3045e41) and eventually a custom encoding (02e9866).
I wanted to revert any special handling of slashes, and simply url-encode/decode. I dug into this recently and I've come to the conclusion that it's actually impossible, using the $location service.
For posterity, I am leaving my notes here:
We are currently calling $location.url(url)
to apply a new URL. The $location.url
implementation decodes the path portion of the url
before applying it as the $location.$$path
. Naively passing a pre-encoded URL such as /path/foo%2Fbar/baz%2Fqux
immediately get decoded to /path/foo/bar/baz/qux
, the param separation are lost. Internally $$path
is set to /path/foo/bar/baz/qux
Since .url()
pre-decodes the incoming URL, we can't use it. Calling $location.path()
directly seemed like a possible alternative since it applies the path without much processing. The $$path
value is set the way we want with our parameters encoded: /path/foo%2Fbar/baz%2Fqux
. However, then the $$url
is built from $$compose()
by calling encodePath
which splits the path on the slashes, then encodes each segment. Because of this, $location.url()
is double encoded as /path/foo%252%bar/baz%252Fquz
.
We landed on purposefully double encoding the slashes, but this caused quite a few issues (most linked to this ticket #1645).
As of 0.2.16, we're custom encoding slashes as ~2F
(using the string
typed parameter) so that the $location service doesn't try to handle them specially.
This is working fine for most of our users. If a user requires a slug (non-encoded slashes) we can support that using a different parameter type that doesn't explicitly encode/decode.
In query parameters, however, we also currently default to the string
parameter type, which is unnecessarily encoding slashes, such as ?queryParam=foo~2Fbar
. We should choose a different default parameter type for query parameters than for path parameters to avoid this. I don't have a ticket for this yet.