You can encode a query string either using either encodeURI or URL. Recently, I noticed that URL encodes spaces differently. I will dicuss why they handle encoding in distinct ways. Before diving into the topic, I will show you how to encode using each method.
// 'https://www.google.com/search?q=programming%20language' encodeURI('https://www.google.com/search?q=programming language')
You can encode a URI using the encodeURI function. However,. it doesn't encode a part of characters that are valid parts of a URI, so that you might need to use the encodeURIComponent function to properly encode query strings or the other components in the URI.
For example, let's say you have a query string q with the value
https://www.google.com/search?q=what is the meaning of &?.
// 'https://www.google.com/search?q=what%20is%20the%20meaning%20of%20&?' encodeURI('https://www.google.com/search?q=what is the meaning of &?')
The &(ampersand) is not converted to & as it should be. Because &(ampersand) can be a valid part of the URI. For this reason, it's always safer to use encodeURIComponent for query strings.
const url = encodeURI('https://google.com/search'); const queryString = `?q=${encodeURIComponent('what is the meaning of &?')}`; // 'https://google.com/search?q=what%20is%20the%20meaning%20of%20%26%3F'; url+queryString;
Since encodeURIX and related functions treat URI as string, you must handle special characters like ? and & yourself. Alternatively, you can simplify the process using the URL.
When using URL to encode, you need to separately handle the base URL and the query string.
const url = 'https://www.google.com/search?q=programming language'; // 'https://www.google.com/search?q=programming language' url.toString();
If you encode everything at once using the URL constructor, as shown in the example above, the query sring might not be encoded properly.
const url = new URL('https://www.google.com/search'); url.searchParams.set('q', 'programming language'); // 'https://www.google.com/search?q=programming+language' url.toString();
By setting the query string via searchParams property of the URL object, you can set the query string.
In this case, the space is converted to . Before explaining why this happens, let's test it with another query string to see how it handles other special characters.
const url = new URL('https://www.google.com/search'); url.searchParams.set('q', 'what is the meaning of &?'); // 'https://www.google.com/search?q=what+is+the+meaning+of+%26%3F' url.toString();
Other special characters are encoded as expected.
Now, let's dive into why these differences happen.
The encodeURIX functions encode according to RFC2396. A URI is not just a location on the internet; it can refer to any type of resource. This is why it is called URI(Uniform Resource Identifier) rather than URL(Uniform Resource Locator).
The URL API encodes according to RFC3986, which is a more recent URI specification.
If you need to achieve this behavior with encodeURI, refer to this. - encodeURIComponent encoding for RF3986).
The URLSearchParams encodes following the rule of the percent encoding. According to the documentation, it replaces spaces with ' '.
While I couldn't find the specification in RFC for this behavior, MDN's encodeURIComponent documentation states:
For application/x-www-form-urlencoded, spaces are to be replaced by , so one may wish to follow a encodeURIComponent() replacement with an additional replacement of with .
This explains why spaces are replaced with ' ' in URLSearchParams, as it follows the application/x-www-form-urlencoded standard.
You may have noticed that URL and URLSearchParams follow a different RFCs.
Let's see some examples.
// 'https://www.google.com/search?q=programming%20language' encodeURI('https://www.google.com/search?q=programming language')
As shown, the URL does not encode brackets and colon, as they are part of the IPv6 address. However, the colon is not encoded as : even though it is a part of query string. It is different from the percent-encoding table.
It means you need to encode the URL and query string separately.
// 'https://www.google.com/search?q=what%20is%20the%20meaning%20of%20&?' encodeURI('https://www.google.com/search?q=what is the meaning of &?')
Now, the URL and query string are encoded properly.
encodeURI, encodeURIComponent, URL, and URLSearchParams functions each serve a different purpose, and you should use them based on your specific needs.
encodeURI: Encodes a URI according to RFC2396. It does not encode characters that are valid parts of a URI. If you need to encode a URI according to RFC3986, refer to this MDN documentation.
encodeURIComponent: Encodes a component of a URI according to RFC2396, such as a path, fragment, or query string. It includes characters that are not encoded by encodeURI.
URL: Encodes a Web URL according to RFC3986.
URLSearchParams: Encode parameters according to the application/x-www-form-urlencoded standard.
If you need to replace the (plus) sign with , you can do so manually, as shown below:
const url = encodeURI('https://google.com/search'); const queryString = `?q=${encodeURIComponent('what is the meaning of &?')}`; // 'https://google.com/search?q=what%20is%20the%20meaning%20of%20%26%3F'; url+queryString;
When working with web development, Restful APIs, or web URLs, the URL is a reliable choice. Additionally, it follows RFC3986, which is newer thanRFC2396.
I hope you found this helpful.
Happy Coding!
The above is the detailed content of Understanding How Spaces Are Encoded: %with encodeURI vs. with URL. For more information, please follow other related articles on the PHP Chinese website!