medialize / URI.js

Javascript URL mutation library
http://medialize.github.io/URI.js/
MIT License
6.26k stars 475 forks source link

toString() automatically encodes #307

Closed PandaWood closed 8 years ago

PandaWood commented 8 years ago

I was sure when I first wrote my code this didn't happen, but is it deliberate that toString() automatically encodes before returning the string?

The documentation for toString() makes no mention of it and it seems pretty important

https://jsfiddle.net/s0t91kge/1/ - a JS fiddle example of this happening - with a URI.js cdn

Maybe it doesn't matter, but I don't want the string encoded because it makes a certain kind of query language that uses square brackets, much easier for advanced users to see the syntax of their query in the query string - it's quite significant for us. Square brackets work without being encoded (despite being technically invalid) - and until it stops working in Chrome/IE we'll continue to take advantage of it.

I'll have have to find another library if this doesn't work, that's all. Odd requirement maybe.

rodneyrehm commented 8 years ago

I was sure when I first wrote my code this didn't happen, but is it deliberate that toString() automatically encodes before returning the string?

It is not .toString() that encodes your query string from ?[Geography].[Geography].[Country].%26[Canada] to ?%5BGeography%5D.%5BGeography%5D.%5BCountry%5D.%26%5BCanada%5D, but .addSearch(), which first parses the query string, than modifies it, then serializes it.

… and until it stops working in Chrome/IE we'll continue to take advantage of it.

I doubt Chrome/IE will move to a stricter parsing of URL than what the URL spec prescribes. Dealing with "properly" encoded URLs helps in different contexts, like when using such URLs in Markdown etc.

This is a question of interoperability. If you make a conscious decision, that's fine. Most people don't and simply assume unencoded characters like [] work everywhere. URI.js is trying to make URLs work for all parties involved.

I'll have have to find another library if this doesn't work, that's all. Odd requirement maybe.

Not as odd as you might think, and not as rare as one might hope.

Anyway, URI.js itself does not provide an option to prevent [] from being encoded. But there are options to patch this behavior in for URI.buildQueryParameter() or URI.encodeQuery(). E.g.

var _encodeQuery = URI.encodeQuery;
URI.encodeQuery = function(string, escapeQuerySpace) {
  return _encodeQuery(string, escapeQuerySpace)
    .replace(/%5B/g, '[')
    .replace(/%5D/g, ']');
};

We could provide another option (like escapeQuerySpace) that accepts an array of characters to maintain in literal, unencoded form. I'm happy to help you on your way to a PR for such a feature.