159

The URL link below will open a new Google mail window. The problem I have is that Google replaces all the plus (+) signs in the email body with blank space. It looks like it only happens with the + sign. How can I remedy this? (I am working on a ASP.NET web page.)

https://mail.google.com/mail?view=cm&tf=0&to=someemail@somedomain.com&su=some subject&body=Hi there+Hello there

(In the body email, "Hi there+Hello there" will show up as "Hi there Hello there")

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user523234
  • 14,323
  • 10
  • 62
  • 102
  • 1
    This is a top search engine hit for "site:stackoverflow.com plus URL encode link". This is acceptable, though there must be an older canonical question somewhere, after nearly 3 years in. For instance, one that is language and framework-agnostic (in case that is the real question, not how it specifically achieved). – Peter Mortensen Nov 27 '22 at 21:30
  • A corresponding [one for Python](https://stackoverflow.com/questions/1695183/) (framework-agnostic). – Peter Mortensen Nov 27 '22 at 21:57
  • A corresponding [one for JavaScript](https://stackoverflow.com/questions/332872/encode-url-in-javascript) (framework-agnostic). – Peter Mortensen Nov 27 '22 at 22:11
  • What is the language and framework-agnostic Stack Overflow question? – Peter Mortensen Nov 27 '22 at 22:26

6 Answers6

234

The + character has a special meaning in [the query segment of] a URL => it means whitespace: . If you want to use the literal + sign there, you need to URL encode it to %2b:

body=Hi+there%2bHello+there

Here's an example of how you could properly generate URLs in .NET:

var uriBuilder = new UriBuilder("https://mail.google.com/mail");

var values = HttpUtility.ParseQueryString(string.Empty);
values["view"] = "cm";
values["tf"] = "0";
values["to"] = "someemail@somedomain.com";
values["su"] = "some subject";
values["body"] = "Hi there+Hello there";

uriBuilder.Query = values.ToString();

Console.WriteLine(uriBuilder.ToString());

The result:

https://mail.google.com:443/mail?view=cm&tf=0&to=someemail%40somedomain.com&su=some+subject&body=Hi+there%2bHello+there

peak
  • 105,803
  • 17
  • 152
  • 177
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 4
    The RFC clearly says that the + sign can be used unencoded, and also if it had to be encoded, there is no reason to turn it into a "space" character. Maybe you can point us to a proper document of a standard mentioning what is that of translating a + symbol into a space symbol and vice-versa. – Pablo Ariel Nov 22 '13 at 18:44
  • 4
    Yeah what are you talking about? I've never seen an RFC or anything that says + means spaces.... – freedrull Dec 14 '15 at 07:56
  • 2
    **Warning:** If you use the `Uri` property of `UriBuilder` you will get a bad result. `uriBuilder.Uri.ToString()` in your example would return `Hi+there+Hello+there`. Using `uriBuilder.Uri.AbsoluteUri` seems to work correctly and http://stackoverflow.com/a/15120429/1931573 suggests this is fixed in .NET 4.5. As far as RFC goes, the HTML 4 spec says the URL querystring is of type `application/x-www-form-urlencoded` which itself defines (+) as meaning space. So it's not an RFC but is part of the HTML standard. – Nick Jun 14 '16 at 23:22
  • @freedrull but it really works this way - that shows the number of upvotes – godblessstrawberry Nov 16 '16 at 21:16
  • 2
    Note that IIS considers this "double encoding" and will often block a url loaded this way with this error: HTTP Error 404.11 - Not Found The request filtering module is configured to deny a request that contains a double escape sequence. – Brady Moritz Nov 09 '18 at 20:51
  • @freedrull According to the [.NET 5 documentation for HTTPUtility.UrlEncode](https://learn.microsoft.com/en-us/dotnet/api/system.web.httputility.urlencode?view=net-5.0), "The UrlEncode method converts each space character to a plus character (+)" (which the result in the answer confirms). According to the [PHP documentation for urldecode](https://www.php.net/manual/en/function.urldecode.php), "Plus symbols ('+') are decoded to a space character". – Dave F May 28 '21 at 03:02
  • 8
    @PabloAriel According to a [W3C document addressing URLs](https://www.w3.org/Addressing/URL/uri-spec.html): "Within the query string, the plus sign is reserved as shorthand notation for a space. Therefore, real plus signs must be encoded. This method was used to make query URIs easier to pass in systems which did not allow spaces." – Dave F May 28 '21 at 03:03
  • This helped me very much! I needed to encode + sign in generated vCard in PHP the normal + sign didnt work. Thank you! – Soufyane Kaddouri Jun 07 '22 at 00:36
32

If you want a plus + symbol in the body you have to encode it as 2B.

For example: Try this

Hamza
  • 171
  • 1
  • 10
Black Frog
  • 11,595
  • 1
  • 35
  • 66
11

In order to encode a + value using JavaScript, you can use the encodeURIComponent function.

Example:

var url = "+11";
var encoded_url = encodeURIComponent(url);
console.log(encoded_url)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
morteza khadem
  • 346
  • 3
  • 8
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent – Drew2 Feb 26 '19 at 21:34
5

Just to add this to the list:

Uri.EscapeUriString("Hi there+Hello there") // Hi%20there+Hello%20there
Uri.EscapeDataString("Hi there+Hello there") // Hi%20there%2BHello%20there

See https://stackoverflow.com/a/34189188/98491

Usually you want to use EscapeDataString which does it right.

Jürgen Steinblock
  • 30,746
  • 24
  • 119
  • 189
4

It's safer to always percent-encode all characters except those defined as "unreserved" in RFC-3986.

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

So, percent-encode the plus character and other special characters.

The problem that you are having with pluses is because, according to RFC-1866 (HTML 2.0 specification), paragraph 8.2.1. subparagraph 1., "The form field names and values are escaped: space characters are replaced by `+', and then reserved characters are escaped"). This way of encoding form data is also given in later HTML specifications, look for relevant paragraphs about application/x-www-form-urlencoded.

Maxim Masiutin
  • 3,991
  • 4
  • 55
  • 72
2

Generally if you use .NET API's - new Uri("someproto:with+plus").LocalPath or AbsolutePath will keep plus character in URL. (Same "someproto:with+plus" string)

but Uri.EscapeDataString("with+plus") will escape plus character and will produce "with%2Bplus".

Just to be consistent I would recommend to always escape plus character to "%2B" and use it everywhere - then no need to guess who thinks and what about your plus character.

I'm not sure why from escaped character '+' decoding would produce space character ' ' - but apparently it's the issue with some of components.

TarmoPikaro
  • 4,723
  • 2
  • 50
  • 62