24

This is in Chrome at least. If my window's URL is https://www.google.com/search?q=JavaScript+URLSearchParams and I run this in the JavaScript console:

url = new URL(document.URL);
urlsp = url.searchParams;
console.log(urlsp.get("q"));

then what gets logged to the console is not JavaScript+URLSearchParams, but JavaScript URLSearchParams. This is a pain because the userscript that I am trying to write needs access to the actual value of the q parameter; and + are not treated the same by the browser. Sure, I could write some code that would process the URL as a string, but that would be tedious and error-prone. The same deal happens with the value %3A in a parameter, but it gets returned as : instead. How do I get URLSearchParams to return the actual value of a URL's parameter?

Melab
  • 2,594
  • 7
  • 30
  • 51
  • 1
    You really need the actual value or a safe value to encode in a url ? if you just need to rewrite the urls search args into a new url, you just need do call the function encodeURIComponent(urlsp.get("q")) – Xavero Aug 04 '17 at 22:20
  • 6
    This will not work I don't think. Spaces in URLs are `%20` not `+`. Javascript's encode function incorrectly changes all spaces to `%20`. In the param part of the URL though, `+` are considered spaces. Also, @Melab, `Javascript+URLSearchParams` is NOT the value. That is the encoded value. The actual value is correctly `JavaScript URLSearchParams`. `encodeURIComponent` will fix other characters like %3A, just do it after you fix the spaces. – Leeish Aug 04 '17 at 22:23
  • 1
    @Xavero I need the actual value. `encodeURIComponent(urlsp.get("q"))` does not do that. – Melab Aug 04 '17 at 22:26
  • @Leeish It is the actual value in the URL. – Melab Aug 04 '17 at 22:26
  • 3
    No it's not. The ACTUAL value is a space. It gets ENCODED to a + sign since URLs can't have spaces. You may see a `+` but that's not the value, that's its encoded value. https://stackoverflow.com/questions/1634271/url-encoding-the-space-character-or-20. The problem is you are oddly trying to process an encoded value instead of the actual value. You say you want the value, but you are actually trying to get an ENCODED value. – Leeish Aug 04 '17 at 22:32
  • 2
    The same with %3A. You say you want the value, but %3A is not the value in the URL. That is an ENCODED character that you want. The only way to get the encoded values from the URL, is to, guess what, reencode the URL. – Leeish Aug 04 '17 at 22:34
  • @Leeish I've written a userscript that accomplishes what I want to do here without using `URLSearchParams`, but it is clunky and too bug prone. But, it is able to distinguish between a `:` and a `%3A` in a URL string. – Melab Aug 04 '17 at 22:38
  • I get what you are saying, but I still think you need to fix your issue during however you are processing the URL. What you are trying to do is a bad idea. But, do what you want. – Leeish Aug 04 '17 at 22:41
  • @Leeish Then why can't I get an answer for that? – Melab Aug 04 '17 at 22:46

3 Answers3

27

URLSearchParams is a representation of the parsed search params. Parsing (specified here) includes decoding the values.

If you don't want to parse the search params, but instead just e.g. split on ampersands and = signs, then don't use url.searchParams. Use instead url.search, and perform the splitting yourself.

Domenic
  • 110,262
  • 41
  • 219
  • 271
9

I could write some code that would process the URL as a string, but that would be tedious and error-prone

I don't know about that, this is a fairly new API and we've been surviving ok without for a long time. There are problems with it anyway, last I checked the API doesn't support parameter arrays like foo[]=1&foo[]=2. It really isn't very complicated and it's not that much code to just roll your own:

class UrlParams {
   constructor(search) {
      this.qs = (search || location.search).substr(1);
      this.params = {};
      this.parseQuerstring();
   }
   parseQuerstring() {
      this.qs.split('&').reduce((a, b) => {
        let [key, val] = b.split('=');
        a[key] = decodeURIComponent(val).replaceAll('+', ' ');
        return a;
      }, this.params);
   }
   get(key) {
      return this.params[key];
   }
}

const params = new UrlParams('?q=Javascript+Stuff');
console.log(params.get('q'));
Massimo
  • 3,171
  • 3
  • 28
  • 41
Rob M.
  • 35,491
  • 6
  • 51
  • 50
4
url = new URL(document.URL);
urlsp = url.searchParams;
console.log(encodeURI(urlsp.get("q")));

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI

thomasmeadows
  • 1,835
  • 12
  • 15
  • URLSearchParams worked weird then this answer saved my time. :) My issue with URLSearchParams was, it never separated by question mark. Still not sure why. – Hoon Nov 27 '21 at 16:37
  • 2
    with you example instead of '+' I am getting '%' – Mykyta Feb 09 '22 at 15:13