Recently in one of the Java web developer interview, one of my readers asked about the difference between x-www-form-url-encoded and multipart/form-data MIME types. In HTTP, there are two ways to send the HTML form data to the server either by using ContentType application/x-www-form-urlencoded or by using multipart/form-data. Even though both can be used to send both text and binary data to the server there is a subtle difference between them. In the case of x-www-form-urlencoded, the whole form data is sent as a long query string.
The query string contains name-value pairs separated by & character e.g. field1=value1&field2=value2 etc. It is similar to URL encoding and normal GET request where data is sent on URL, but form data goes inside POST request body and they are encoded like that.

Also, both reserved and non-alphanumeric characters are replaced by '%HH', a percent sign and two hexadecimal digits representing the ASCII code of the character e.g. space is replaced by %20 character in URL.

On the other hand, when you choose HTTP header ContentType=multipart/form-data then data is sent in chunks to a server where the boundary is made by a character which should not appear in the content.

This is achieved by using a suitable encoding e.g. choosing a base64 encoding and then making a character outside of base64 encoding scheme as the boundary. The multipart/form-data is often used while uploading files to the server.

x-www-form-urlencoded vs multipart/form-data

Let's see some more important points about both x-www-form-urlencoded and multipart/form-data content type in HTTP:

1) Both are MIME type which is sent on HTTP header ContentType e.g.ContentType: application/x-www-form-urlencodedContentType: application/multipart/form-data

2) Both are ways to send name-value pairs data to the server i.e. the details you have entered into an HTML form is sent by using these two to the server.

3) Both content types are used while sending form data as a POST request.

4) The x-www-form-urlencoded is used more generally to send text data to the server while multipart/form-data is used to send binary data, most notably for uploading files to the server.

5) It's a requirement for user agents like a browser to support both MIME types.

6) In the case of x-www-form-urlencoded, all name value pairs are sent as one big query string where alphanumeric and reserved character are url encoded i.e. replaced by % and their hex value e.g. space is replaced by %20. The length of this string is not specified by HTTP specification and depends upon server implementation.

7) In the case of multipart/form-data, each part is separated by a particular string boundary (chosen specifically so that this boundary string does not occur in any of the "value" payloads.

8) The multipart/form-data is more efficient than x-www-form-urlencoded because you don't need to replace one character with three bytes as required by URL encoding.

Should you use multipart/form-data Always?

Given the multipart/form-data is more efficient than x-www-form-urlencoded, some of you may question Why not use multipart/form-data all the time? Well, it's not the idea.

For short alphanumeric values (like most of the web forms), the overhead of adding all of the MIME headers is going to significantly outweigh any savings you will make from more efficient binary encoding.

Hence, it is advised to use x-www-form-urlencoded when you have to send form data e.g. most of the web form which asks you to enter values and use multipart/form-data when you have to upload files to the server as used here.

That's all about the difference between x-www-form-urlencoded and multipart/form-data content type headers in HTTP. Even though both are used to send the form data or a list of key-value pairs to the server, x-www-form-urlencoded is more efficient and should be used for all general purpose, while multipart/form-data should exclusively be used for uploading files to the server.