skip to Main Content

When posting data to a controller from JavaScript:

async function createClient() {
  let response = await fetch($("#API_URL").val() + "/clients", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify($("#frmClient").serializeJSON()),
  });
  let data = await response.json();
  return data;
}

When I tried to use just $("#frmClient").serializeJSON(), which returns a JSON object, then the post failed. So why is it mandatory to stringify?

3

Answers


  1. There’s no such thing as a JSON object. You appear to be using this plugin which, contrary to its name, returns an object, not JSON.

    You have to convert that object to JSON in order to have the request body be JSON.

    Login or Signup to reply.
  2. When using the fetch API to make an HTTP request, the content that goes into the body of the request is determined by the ‘content-type’ header. If you set the ‘content-type’ to ‘application/json’, you’re telling the server that the request body contains text data that can be deserialized into the data structure the server expects for JSON.

    Before you call JSON.stringify on an object, that object is essentially just a sequence of bytes. While the JavaScript engine that created it understands these bytes, other programming languages or even different versions of JavaScript engines may not interpret them correctly. These bytes might not even be stored together in memory but are scattered across memory, connected only by pointers.

    To send this data to a different environment or server, you need to encode it in a format that both the sender and receiver understand. JSON is a common choice because it shares a syntactical resemblance with JavaScript in its textual representation. However, the binary representation of data in JSON has little in common with binary representation of that same data in JavaScript.

    So, to transmit data over HTTP, you must call JSON.stringify on an object and send the resulting data string with a ‘content-type’ of ‘application/json’. Not using JSON.stringify means that JavaScript won’t know how to order bytes in a way that the receiver can understand them.

    Login or Signup to reply.
  3. So why is it mandatory to stringify?

    I think you might have a misunderstanding about how HTTP works, and how the Fetch API exposes it.

    In your code, you use the Fetch API. When you use fetch(), JavaScript tells the browser (your computer) to open a connection to another computer/server on the internet and send an HTTP request. Under the hood, this HTTP request is mostly just a bunch of text (strings) being sent over a TCP socket (and optionally encrypted if using HTTPS).

    Now, the HTTP protocol is pretty complicated, and it needs to be complicated to support all of the modern features of the web you use today. There are extensions to send binary data such as images or videos, and there’s streaming to support technologies like WebSockets. However, you don’t have to worry about most of this because the Fetch API covers it up with some nice functions.

    So back to your question: why do you have to stringify an object in the body of an HTTP request? Well, as I said previously, HTTP is just text at the end of the day. HTTP, and thus fetch() lets you send pretty much whatever you want in the body. Most of the time this is stuff like HTML, but you can also send objects as JSON data. You tell the server what type of data you’re sending with the Content-Type header. Your code set this to application/json, which says that you’re going to send an object. But remember: HTTP is text, so you can’t just send an object, you must first convert it into text. You can do this a number of ways, but the most common and the way you are using is a standard called JSON. When you call JSON.stringify() you turn that object into text according to how JSON specifies it should be done.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search