57

This should be a simple task, but I can't seem to find a solution.

I have a basic string that is being passed through as a query string parameter like this one: This+is+a+message+with+spaces. I would like to decode that parameter using JavaScript to This is a message with spaces, but I cannot seem to get it to decode.

I've tried decodeURI('This+is+a+message+with+spaces') but the result still contains the + signs.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
user852367
  • 1,000
  • 1
  • 9
  • 15
  • 1
    http://stackoverflow.com/questions/4292914/javascript-url-decode-function – locrizak Aug 20 '12 at 17:59
  • 2
    The URL needs to be encoded to be decoded ;) – davidbuzatto Aug 20 '12 at 18:02
  • 1
    Locrizak, `decodeURIComponent('This+is+a+message+with+spaces')` still returns `This+is+a+message+with+spaces`. `encodeURIComponent('This+is+a+message+with+spaces')` returns `This%2Bis%2Ba%2Bmessage%2Bwith%2Bspaces`. I must be missing something because I'm not seeing how this is solving my problem. – user852367 Aug 20 '12 at 18:02

5 Answers5

79

Yes it is true that decodeURIComponent function doesn't convert + to space. So you have to replace the + using replace function.

Ideally the below solution works.

var str_name = 'This+is+a+message+with+spaces';
decodeURIComponent((str_name + '').replace(/\+/g, '%20'));
Supriti Panda
  • 1,281
  • 1
  • 11
  • 12
  • 1
    This is the better answer. `encodeURIComponent` may well choose not to encode spaces to `+`, preferring `%20`, but the URI may come from somewhere else, and `+` is a perfectly valid encoding for a space that for unknown reasons JS's `decodeURIComponent` decides to ignore. – abligh Jan 30 '15 at 20:43
  • + is not a valid uri encoding for space. some websites just choose to replace spaces in urls with `+`, `-`, `_`, etc. because it's more readable, but it's not standardized – 12Me21 Sep 05 '21 at 02:02
33

Like it was pointed out already, decodeURI function doesn't convert + to space, but there are some things worth to realize here:

  • decodeURI is meant to be used for whole URI, i.e. it doesn't decode separators like ?, &, =, +, etc.
  • for decoding parameters decodeURIComponent should be used
    (worth to have a look at: What is the difference between decodeURIComponent and decodeURI? )
  • string that you are trying to decode might actually contain + encoded as %2B, thus you should not replace + after the conversion since you might lost + signs that you actually want there, e.g. something?num=%2B632+905+123+4567 should become:
    something?num=+632 905 123 4567
    since you are probably going to extract the number: +632 905 123 4567

So the correct way to do this is:

var str = 'something?num=%2B632+905+123+4567';
decodeURIComponent( str.replace(/\+/g, '%20') );
Community
  • 1
  • 1
LihO
  • 41,190
  • 11
  • 99
  • 167
28

The plus sign is not encoded/decoded. To see the decode function working, you need to pass a encoded URI first. Take a look:

encodeURI( "http://www.foo.com/bar?foo=foo bar jar" )

Will generate: http://www.foo.com/bar?foo=foo%20bar%20jar, i.e., the encoded URI.

decodeURI( "http://www.foo.com/bar?foo=foo%20bar%20jar" )

Will generate: http://www.foo.com/bar?foo=foo bar jar, i.e., the decoded URI.

davidbuzatto
  • 9,207
  • 1
  • 43
  • 50
11

The below code will decode and gives you the params in form of objects

export function getParamsFromUrl(url) {
    url = decodeURI(url);
    if (typeof url === 'string') {
        let params = url.split('?');
        let eachParamsArr = params[1].split('&');
        let obj = {};
        if (eachParamsArr && eachParamsArr.length) {
            eachParamsArr.map(param => {
                let keyValuePair = param.split('=')
                let key = keyValuePair[0];
                let value = keyValuePair[1];
                obj[key] = value;
            })
        }
        return obj;
    }
}
Varsha Jadhav
  • 403
  • 1
  • 4
  • 14
1

I created my own string methods to support the needed encoding/decoding. These methods will handle the + encoding and decoding properly, allowing you to have plusses (+) in your string and still have the original spaces be encoded as +'s.

String.prototype.plusEncode = function() {
    return encodeURIComponent(this).replace(/\%20/gm,"+");
}

String.prototype.plusDecode = function() {
    return decodeURIComponent(this.replace(/\+/gm,"%20"));
}
Harvey
  • 19
  • 5