Form data is indeed sent inside the HTTP body of a POST request
if I dissasemble a POST request:
Request line > POST /index.php HTTP/1.1
Headers > Cache-Control: max-age=0
> Origin: http://localhost:8080
> Upgrade-Insecure-Requests: 1
> DNT: 1
The content
type header > Content-Type: application/x-www-form-urlencoded
Also headers > User-Agent: Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/85.0.4183.121Safari/537.36
> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
> Sec-Fetch-Site: same-origin
> Sec-Fetch-Mode: navigate
> Sec-Fetch-User: ?1
> Sec-Fetch-Dest: document
> Referer: http://localhost:8080/index.php
> Accept-Encoding: gzip,deflate,br
> Accept-Language: cs-CZ,cs;q=0.9,en;q=0.8
Empty line >
Body > fname=John&lname=Doe&formsubmitted=5000
As you can see, among the awful mess of other headers (I apologize for that), there is a Content-Type header, this specifies the MIME type of the content in HTTP Body, this is usually application/x-www-form-urlencoded for POST forms, this is the one you see in the HTTP Request above.
Here, the Body contains the form data (separated by &) from the following form:
<form action="/index.php" method="POST">
<input type="text" id="fname" name="fname" value=""><br>
<input type="text" id="lname" name="lname" value=""><br>
<input type="hidden" id="formsubmitted" name="formsubmitted" value="5000"><br>
<input type="submit" value="Submit">
</form>
Another one that is used is multipart/form-data, citing MIME type reference on developer.mozzila.com: "As a multipart document format, it consists of different parts, delimited by a boundary (a string starting with a double dash --). Each part is its own entity with its own HTTP headers, Content-Disposition, and Content-Type for file uploading fields.", this definition also includes the following example:
Content-Type: multipart/form-data; boundary=aBoundaryString
(other headers associated with the multipart document as a whole)
--aBoundaryString
Content-Disposition: form-data; name="myFile"; filename="img.jpg"
Content-Type: image/jpeg
(data)
--aBoundaryString
Content-Disposition: form-data; name="myField"
(data)
--aBoundaryString
(more subparts)
--aBoundaryString--
Although I never actually encountered the multipart/form-data MIME type, you must acknowledge it when dealing with POST HTTP Requests
As to answer your other question in more detail "Also what is application/x-www-form-urlencoded in the header?"
application/x-www-form-urlencoded is a MIME type, the urlencoded in it means that the form data is encoded in the same way it would be in a GET request, each field is separated by a & character and the fields are in the format of name=value
And to what you wrote "I know that a http request consists of [Method][Header][URL][Params][Body]", this is wrong, a HTTP request consists of those but not in this order, the actual order is this:
Method Requested_Resource(and GET parameters if any) HTTP_Version \r\n
Headers ('\r\n' after each header)
\r\n
Body