fix: always encode = in query key and values#164
fix: always encode = in query key and values#164undermoonn wants to merge 1 commit intounjs:mainfrom
= in query key and values#164Conversation
= in query key and values
| */ | ||
| export function encodeQueryKey(text: string | number): string { | ||
| return encodeQueryValue(text).replace(EQUAL_RE, "%3D"); | ||
| return encodeQueryValue(text); |
There was a problem hiding this comment.
/cc @posva was there any specific reason = wasn't being encoded before? (This was taken from vue-router utils i guess)
There was a problem hiding this comment.
I don't remember exactly but I think that it's because it wasn't necessary to encode the = within a value since it already appeared after a key and the parser won't be expecting one until it gets into the state of reading a key. In other words, ?q=value=with=&b=other is parsable as the = only has a meaning when parsing a key
There was a problem hiding this comment.
Indeed it is parsable and valid without encoding.. However URL sppec encoded like this. I think it would be nice if we could preserve a consistent behavior between ufo, vue-router (and URL) spec if you are okay I can make a PR to vue-router as well to keep them in sync and avoid mistmatching behavior between different places (as we use ufo in nuxt)
There was a problem hiding this comment.
I will give it a look in 2-3 weeks. I did a lot of testing in different browsers when writing that code and I imagine that if I added 2 functions instead of one, there must be a reason 😆
There was a problem hiding this comment.
Here is the discrepancy:
- When directly entering some characters in a URL, the browser encodes some of them. The
=within a query value, isn't encoded e.g. reads as=inlocation.href. URLSearchParams()encodes=
Depending on the browsers, they display the value on the URL as encoded or not, therefore I tried, as much as possible, to display the original characters across browsers when they didn't need encoding. Also, Vue Router supports some browsers that do not have full URLSearchParams() support.
BTW I don't think the URL spec specifies that = must be encoded in query values.
When I did the research on what was supported and what the spec said, it turned out encodeURIComponent() was doing too much in some scenarios and that's why it's not used in vue router. Unless there is a bug, changing this behavior in vue router would be tiny breaking change, so it's better to keep it the way it is, being more readable across browsers.
Cheers
There was a problem hiding this comment.
Thanks for detailed feedback. Is there a list of officially supported browsers by vue-router btw? And do you think it would be an issue if ufo (in a major version) choose to always encode things like = with URLSearchParams compatibility? (basically: does vue-router guarantees to decode encoded values like = in query even if it doesn't encodes it?)
There was a problem hiding this comment.
We don't have a list, it's the same as Vue 3 😅
It's better to try by yourself, there might be problems with redirects and reloads. However, if I were you, since there is currently no problem with the encoding, I wouldn't change it in ufo either. The opened issue is fundamentally wrong, specifically, this statement is not true:
When we encode a query not a url. we should use encodeURIComponent not encodeURI.
The spec specifies encode sets, not functions to use. Since the issue lacks a real-world scenario with a problem, I would personally wait to see if this fixes anything, if not, it's better to keep the current behavior for the reasons I mentioned in my previous comment
There was a problem hiding this comment.
The thing is, for the next major version of UFO I am thinking of relying on native URL and URLSearchParams for encoding and parsing since it has good coverage in platforms (I guess at least all Vue 3 supported targets -- have to double check) and as a result, we might end up with compatibility issues if didn't anticipate edge cases.
Thanks for feedbacks anyway, if we want to do this, i will certainly reach you out for more through tests across ecosystem packages.
There was a problem hiding this comment.
FYI I wanted to rely on URL and URLSearchParams but there were small bugs in some old versions of browsers that forced me to not use them yet. I do hope to use them in the future major version of Vue Router though!
Codecov Report
@@ Coverage Diff @@
## main #164 +/- ##
=======================================
Coverage 94.91% 94.92%
=======================================
Files 7 7
Lines 846 847 +1
Branches 177 177
=======================================
+ Hits 803 804 +1
Misses 43 43
|
|
Following up discussion, it seems we are not going to change behavior at least until next major version that likely will use If you spot any bugs with this current behavior we can certainly reconsider. and thanks for PR @undermoonn anyway ❤️ |
🔗 Linked issue
resolves #162
❓ Type of change
📚 Description
URL ponyfill output is different from encoding query value
=withnew URLnew URLwithQueryhttps://url.spec.whatwg.org/#concept-urlencoded-serializer
From the URL serializing document,
encodeQueryValueshould be same asencodeQueryKey📝 Checklist