Why should Spaces be encoded in HTTP requests? Today we walk into the RFC documentation and W3C documentation to take a look at this epic pit.

1.% 20or+

To begin, let’s take a quick test. Type blank test (with a space between blank and test) into the browser. Let’s see what the browser does:

You can see from the GIF that the browser parses whitespace as a plus sign “+”.

Does it feel weird? Let’s do another test, using some of the functions provided by the browser:

encodeURIComponent("blank test") // "blank%20test"
encodeURI("q=blank test")        // "q=blank%20test"
new URLSearchParams("q=blank test").toString() // "q=blank+test"
Copy the code

Code is not a lie, in fact, the above results are correct, encode results are not the same, because URI specification and W3C specification conflict, will make this kind of confusing error event.

2. Conflicting agreements

Let’s start by looking at reserved words in urIs that do not participate in encoding. There are two categories of reserved characters:

  • Gen – delims:: / ? # [ ] @
  • Sub – delims:! $ & ' ( ) * + . ; =

The URI encoding rules are also simple: unbounded characters are converted to hexadecimal, followed by a percent sign.

An unsafe character like a space in hexadecimal format is 0x20, followed by a percent sign % is %20:

So when you look at encodeURIComponent and encodeURI, it is completely correct.

Since the conversion of space to %20 is correct, what about the conversion to +? It’s time to take a look at the history of HTML forms.

In the early days of web pages without AJAX, data was submitted via HTML form forms. The form submission method can be GET or POST, and you can test it on the MDN form entry:

After testing, we can see that Spaces are converted to plus signs in form submission, and this coding type is Application/X-www-form-urlencoded, which is defined in WHATWG specification as follows:

Here basically solved the case, URLSearchParams do encode time, according to this specification. I found the URLSearchParams Polyfill code, which maps %20 to + :

replace = {
    '! ': 21 '%'."'": '% 27'.'(': 28 '%'.') ': '% 29'.'~': '%7E'.'% 20': '+'.// <= that's it
    00 '%': '\x00'
}
Copy the code

The specification also explains this encoding type:

The application/x-www-form-urlencoded format is in many ways an aberrant monstrosity, the result of many years of implementation accidents and compromises leading to a set of requirements necessary for interoperability, but in no way representing good design practices. In particular, readers are cautioned to pay close attention to the twisted details involving repeated (and in some cases nested) conversions between character encodings and byte sequences. Unfortunately the format is in widespread use due to the prevalence of HTML forms.

This is not a good design, and unfortunately with the popularity of HTML forms, this format has become widespread

In fact, the above paragraph is the same meaning: this device is designed to 💩, but the accumulation of hard work, we should bear with it

3. A one-sentence summary

  • In URI specification, encode is %20; in application/ X-www-form-urlencoded format, encode is +

  • In actual business development, it is best to use the industry’s mature HTTP request library to encapsulate the request, the tedious work framework is dry;

  • If you have to submit data in application/ X-www-form-urlencoded format using native AJAX, don’t concatenated parameters manually, use URLSearchParams to process the data and avoid all sorts of nasty coding conflicts.

5. Thank you

That’s the end of this article, please like 👍 oh, thank you, this is really important to me

Article recommendations

This article is excerpted from my long article on the dark pits in the HTTP specification. To learn more, click here.

More recommendations:

  • HTTP | X – Forwarded – cold knowledge is For get the real IP?
  • Five of the most confusing nuggets in the webpack
  • React Native Performance Optimization Guide analyzes six points of RN performance optimization from the perspective of the rendering layer, and explains the implementation principle of FlatList in graphic form
  • Web Scraper describes a small browser crawler plug-in that provides simple data crawlers




Finally, I would like to recommend my personal official account “Lu Egg Lab”. I usually share some front-end technology and data analysis content. If you are interested, you can pay attention to the following: