POST request to encode data (part 1)

No way, because the article is too long, nuggets on a one-time display can not be, so to be divided into two parts to send, we read the first half, remember to read the second half

  • POST request to encode data (part 1)
    • URLSearchParams
      • Read and transform operations for URLSearchParams
      • url.searchParams
      • Make URLSearchParams the body of the Fetch
  • reference
    • Finally, welcome to my official account: Joshua, the front end upperclassman

Ok, here we go. Let’s start with a code example:

async function isPositive(text) {
  const response = await fetch(`http://text-processing.com/api/sentiment/`, {
    method: 'POST',
    body: `text=${text}`,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
  });
  const json = await response.json();
  return json.label === 'pos';
}
Copy the code

This code is poorly written and can cause security problems. Why is that? ${text} =${text}

Unescaped text is added to a format with a defined encoding. That is, the text variable, which is written directly into the body of the request without being escaped (or coded), in this case ‘Content-Type’: ‘Application/X-www-form-urlencoded’.

This is a bit like SQL/HTML injection, because something intended to be a “value” (meaning something like a text variable) can interact directly with the format.

So, I’ll delve into the right approach, while also taking a look at some related, lesser-known apis:

URLSearchParams

URLSearchParams can be used to encode and decode Application/X-www-form-urlencoded data. It’s very convenient because, well…

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. — The URL standard

. So, yes, it is not recommended to encode/decode application/ X-www-form-urlencoded data yourself.

Here’s how URLSearchParams works:

const searchParams = new URLSearchParams();
searchParams.set('foo', 'bar');
searchParams.set('hello', 'world');

// Logs 'foo=bar&hello=world'
console.log(searchParams.toString());
Copy the code

The URLSearchParams constructor can also take an array of [key, value] pairs, or an iterator that produces [key, value] pairs:

const searchParams = new URLSearchParams([
  ['foo', 'bar'],
  ['hello', 'world'],
]);

// Logs 'foo=bar&hello=world'
console.log(searchParams.toString());
Copy the code

Or an object:

const searchParams = new URLSearchParams({
  foo: 'bar',
  hello: 'world',
});

// Logs 'foo=bar&hello=world'
console.log(searchParams.toString());
Copy the code

Or a string:

const searchParams = new URLSearchParams('foo=bar&hello=world');

// Logs 'foo=bar&hello=world'
console.log(searchParams.toString());
Copy the code

Read and transform operations for URLSearchParams

There are a number of methods for URLSearchParams that can be read and converted into arrays or objects, as detailed in MDN.

Its iterators come in handy if there are scenarios where you want to process all the data:

const searchParams = new URLSearchParams('foo=bar&hello=world');

for (const [key, value] of searchParams) {
  console.log(key, value);
}
Copy the code

This also means you can easily convert it to an array of [key, value] pairs:

// To [['foo', 'bar'], ['hello', 'world']]
const keyValuePairs = [...searchParams];
Copy the code

Or use it with an API that supports iterators that generate key-value pairs, such as Object.fromEntries, to convert it to an Object:

// To { foo: 'bar', hello: 'world' }
const data = Object.fromEntries(searchParams);
Copy the code

Note, however, that converting to objects is sometimes lossy: it may cause something worth losing

const searchParams = new URLSearchParams([
  ['foo', 'bar'],
  ['foo', 'hello'],
]);

// Logs "foo=bar&foo=hello"
console.log(searchParams.toString());

// To { foo: 'hello' }
const data = Object.fromEntries(searchParams);
Copy the code

url.searchParams

The URL object has a searchParams property that makes it very easy to get the request parameters:

const url = new URL('https://jakearchibald.com/?foo=bar&hello=world');

// Logs 'world'
console.log(url.searchParams.get('hello'));
Copy the code

Unfortunately, there is no location. SearchParams property on window.location.

This is because window.location is complicated by how some of its properties work across sources. Such as setting the otherWindow. Location. Href across the source work, but does not allow access to it.

But anyway, we’ll fix it so that we can easily get the request parameters from the address bar:

// Boo, undefined
location.searchParams;

const url = new URL(location.href);
// Yay, defined!
url.searchParams;

// Or:
const searchParams = new URLSearchParams(location.search);
Copy the code

Make URLSearchParams the body of the Fetch

Ok, now let’s get down to business. The code in the example at the beginning of this article has some problems because it does not escape input:

const value = 'hello&world'; const badEncoding = `text=${value}`; / / 😬 Logs [[' text ', 'hello,'], [' world ', ' ']]. The console log ([... new URLSearchParams (badEncoding)]); const correctEncoding = new URLSearchParams({ text: value }); // Logs 'text=hello%26world' console.log(correctEncoding.toString());Copy the code

For ease of use, the URLSearchParams object is a body that can be used directly to Request Request or respond to Response, so the “correct” version of the code at the beginning of this article is:

async function isPositive(text) {
  const response = await fetch(`http://text-processing.com/api/sentiment/`, {
    method: 'POST',
    body: new URLSearchParams({ text }),
  });
  const json = await response.json();
  return json.label === 'pos';
}
Copy the code

If URLSearchParams is used as the body, the Content-Type field is automatically set to Application/X-www-form-urlencoded

You can’t read the body that requests Request or responds to Response as an URLSearchParams object, but there are ways around this…

Please move on to the next section, decryption… (I also don’t want to split the article into two parts.)

reference

  • Encoding data for POST requests

Finally, welcome to my official account: Joshua, the front end upperclassman