16

I need to send data by POST method.

For example, I have the string "bla&bla&bla". I tried using encodeURI and got "bla&bla&bla" as the result. I need to replace "&" with something correct for this example.

What kind of method should I call to prepare correct POST data?

UPDATED:

I need to convert only charachters which may broke POST request. Only them.

user626528
  • 13,999
  • 30
  • 78
  • 146
Dmitry
  • 14,306
  • 23
  • 105
  • 189

6 Answers6

23
>>> encodeURI("bla&bla&bla")

"bla&bla&bla"

>>> encodeURIComponent("bla&bla&bla")

"bla%26bla%26bla"
Álvaro González
  • 142,137
  • 41
  • 261
  • 360
  • 2
    If one is trying to mimic exactly what a browser would upload, one should note that web forms (in particular those without file attachments) use the `application/x-www-form-urlencoded` encoding. In this format, browsers will encode spaces as `+` characters rather than `%20` (as is the case for `encodeURIComponent`) -- the encoding is ambiguous, but either option decodes to the same data. [See format here.](https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1) I would emphasize that `encodeURIComponent` is the way to go in this answer. – init_js May 12 '17 at 08:30
  • I must say that this solution doesn't work. ! are not encoded bu encodeeURIComponent – Cecile May 07 '18 at 10:02
  • @Cecile Neither are `.` or `a`. Why should they? – Álvaro González May 07 '18 at 10:53
  • I thought it was the reason why it failed in my case but apparently not, I just forgot the HTTP header – Cecile May 08 '18 at 11:46
14

You can also use escape() function.The escape() function encodes a string. This function makes a string portable, so it can be transmitted across any network to any computer that supports ASCII characters.This function encodes special characters, with the exception of: * @ - _ + . /

var queryStr = "bla&bla&bla";
alert(queryStr);               //bla&bla&bla
alert(escape(queryStr));       //bla%26bla%26bla

Use unescape() to decode a string.

var newQueryStr=escape(queryStr);
alert(unescape(newQueryStr));   //bla&bla&bla

Note:

    escape() will not encode: @*/+

    encodeURI() will not encode: ~!@#$&*()=:/,;?+'

    encodeURIComponent() will not encode: ~!*()'

After some search on internet, I got the following:

escape()

Don't use it.

encodeURI()

Use encodeURI when you want a working URL. Make this call:

encodeURI("http://www.google.com/a file with spaces.html")

to get:

http://www.google.com/a%20file%20with%20spaces.html

Don't call encodeURIComponent since it would destroy the URL and return

http%3A%2F%2Fwww.google.com%2Fa%20file%20with%20spaces.html

encodeURIComponent()

Use encodeURIComponent when you want to encode a URL parameter.

param1 = encodeURIComponent("http://xyz.com/?a=12&b=55")

Then you may create the URL you need:

url = "http://domain.com/?param1=" + param1 + "&param2=99";

And you will get this complete URL:

http://www.domain.com/?param1=http%3A%2F%2Fxyz.com%2F%Ffa%3D12%26b%3D55¶m2=99

Note that encodeURIComponent does not escape the ' character. A common bug is to use it to create html attributes such as href='MyUrl', which could suffer an injection bug. If you are constructing html from strings, either use " instead of ' for attribute quotes, or add an extra layer of encoding (' can be encoded as %27).

REF:When are you supposed to use escape instead of encodeURI / encodeURIComponent?

Also, as you are using JQuery, take a look at this built-in function.

Community
  • 1
  • 1
Bhushan Firake
  • 9,338
  • 5
  • 44
  • 79
  • Will it be more correct for POST method? I can't change code of POST receiver. I need to use URL-encoding in compliance with API. – Dmitry Feb 12 '13 at 10:51
  • But I don't know which method is the best for POST data:( – Dmitry Feb 12 '13 at 10:54
  • @Altaveron It depends on what characters you want to post. Check if your POSt contains the characters given in my answer and then use the function that encodes them. – Bhushan Firake Feb 12 '13 at 10:55
  • Data may contain any character. But receiver may not decode them. Also I need to convert only charachters which may broke POST request. Only them. – Dmitry Feb 12 '13 at 10:56
  • 1
    @Altaveron : Stick with encodeURIComponent(). encodeURI() does not bother to encode many characters that have semantic importance in URLs (e.g. "#", "?", and "&"). escape() does not bother to encode "+" characters, which will be interpreted as encoded spaces on the server (and, as pointed out by others here, does not properly URL-encode non-ASCII characters). – Bhushan Firake Feb 12 '13 at 10:58
  • @Altaveron You are using JQuery, then see last line of my answer...hope I was helpful..!! – Bhushan Firake Feb 12 '13 at 11:06
  • [ESCAPE()](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/escape) is **deprecated**. Just thought to write it down in case someone wants to use it :) – Erenor Paz Sep 29 '16 at 15:14
6

Use encodeURIComponent() as encodeURI() will not encode: ~!@#$&*()=:/,;?+'

This has been explained quite well at the following link:

http://xkr.us/articles/javascript/encode-compare/

1

More recent DOM APIs for URLSearchParams (and via URL, possibly others too) handle encoding in some cases. For example, create or use an existing URL object (like from an anchor tag) I map entries of an object as key value pairs for URL encoded params (to use for GET/POST/etc in application/x-www-form-urlencoded mimetype). Note how the emoji, ampersand and double quotes are encoded without any special handling (copied from the Chrome devtools console):

var url = new URL(location.pathname, location.origin);
    Object.entries({a:1,b:"",c:'"stuff&things"'}).forEach(url.searchParams.set, url.searchParams);
    url.search;
    "?a=1&b=%F0%9F%8D%BB&c=%22stuff%26things%22"

fetch(url.pathname, {
    method: 'POST',
    headers: new Headers({
        "Content-type": "application/x-www-form-urlencoded"
    }),
    // same format as GET url search params a&b&c
    body: url.searchParams
}).then((res)=>{ console.log(res); return res }).catch((res)=>{ console.warn(res); return res; });
jimmont
  • 2,304
  • 1
  • 27
  • 29
0

I want POST the javascript-created hidden form.

So the question is if encodeURIComponent() should be used on each POST variable.

I haven't found the answer for Dmitry's (and my) question in this thread. But I have found the answer in this thread.

In case of form/POST where you have upload field(s) you must use <form enctype="multipart/form-data">, if no upload field is used, you should choose yourself as described here. Submitting the form should do the job completly, so there is no need to use encodeURIComponent() explicitly.

If you create a Http POST without using a form or without some library which creates a Http POST from your data, then you need choose an enctype= and join data yourselves.

This will be easy for application/x-www-form-urlencoded, where you will use encodeURIComponent() on each value and join them exactly as for GET request.

If you decide use multipart/form-data then ....? You should google more how to encode and join them in such case.

Community
  • 1
  • 1
mirek
  • 1,140
  • 11
  • 10
0

For anyone still wondering, there is a much easier way to do this now. You could use URLSearchParams[1] class in JS (Docs). Which accepts an Object parameter in the constructor. You can then call .toString() on the instance to get the actual parameters, encoded using encodeURIComponent()

Then, in the actual request, you need to specify the Content-Type header to be application/x-www-form-urlencoded, and simply set the body property of the request to the String returned by the params.toString() method.

const data = {"hello[World}": ``, "goodbye": ``};
const params = new URLSearchParams(data);

const endpoint = `https://example.com`;

fetch(endpoint, {
  method: `POST`,
  headers: {
    "Content-Type": `application/x-www-form-urlencoded`,
  },
  body: params.toString(), // hello%5BWorld%7D=%F0%9F%A5%91&goodbye=%F0%9F%98%9E
});