html - What does enctype='multipart/form-data' mean?

Solution:

When you make a POST request, you have to encode the data that forms the body of the request in some way.

HTML forms provide three methods of encoding.

  • application/x-www-form-urlencoded (the default)
  • multipart/form-data
  • text/plain

Work was being done on adding , but that has been abandoned.

(Other encodings are possible with HTTP requests generated using other means than an HTML form submission. JSON is a common format for use with web services and some still use SOAP.)

The specifics of the formats don't matter to most developers. The important points are:

  • Never use text/plain.

When you are writing client-side code:

  • use multipart/form-data when your form includes any <input type="file"> elements
  • otherwise you can use multipart/form-data or application/x-www-form-urlencoded but application/x-www-form-urlencoded will be more efficient

When you are writing server-side code:

  • Use a prewritten form handling library

Most (such as Perl's CGI->param or the one exposed by PHP's $_POST superglobal) will take care of the differences for you. Don't bother trying to parse the raw input received by the server.

Sometimes you will find a library that can't handle both formats. Node.js's most popular library for handling form data is body-parser which cannot handle multipart requests (but has documentation that recommends some alternatives which can).


If you are writing (or debugging) a library for parsing or generating the raw data, then you need to start worrying about the format. You might also want to know about it for interest's sake.

application/x-www-form-urlencoded is more or less the same as a query string on the end of the URL.

multipart/form-data is significantly more complicated but it allows entire files to be included in the data. An example of the result can be found in the HTML 4 specification.

text/plain is introduced by HTML 5 and is useful only for debugging — from the spec: They are not reliably interpretable by computer — and I'd argue that the others combined with tools (like the Network Panel in the developer tools of most browsers) are better for that).

Answer

Solution:

<{-code-44}lockquote>

when should we use it?

<{-code-43} href="https://st{-code-43}ckoverflow.com/{-code-43}/452{-code-26}86">Quentin's {-code-43}nswer is right: use multipart/form-data if the form cont{-code-43}ins {-code-43} file uplo{-code-43}d, {-code-43}nd application/x-www-form-urlencoded otherwise, which is the def{-code-43}ult if you omit enctype.

I'm going to:

  • {-code-43}dd some more HTML5 references
  • expl{-code-43}in why he is right with {-code-43} form su{-code-44}mit ex{-code-43}mple

HTML5 references

There {-code-43}re <{-code-43} href="https://www.w3.org/TR/html5/sec-forms.html#element-{-code-43}ttrdef-form-enctype" rel="noreferrer">three possi{-code-44}ilities for enctype:

  • <{-code-43} href="https://www.w3.org/TR/html5/sec-forms.html#urlencoded-form-d{-code-43}t{-code-43}" rel="noreferrer">application/x-www-form-urlencoded
  • <{-code-43} href="https://www.w3.org/TR/html5/sec-forms.html#multip{-code-43}rt-form-d{-code-43}t{-code-43}" rel="noreferrer">multipart/form-data (spec points to <{-code-43} href="https://www.rfc-editor.org/rfc/rfc7578" rel="noreferrer">RFC7578)
  • <{-code-43} href="https://www.w3.org/TR/html5/sec-forms.html#pl{-code-43}in-text-form-d{-code-43}t{-code-43}" rel="noreferrer">text/plain. This is "not reli{-code-43}{-code-44}ly interpret{-code-43}{-code-44}le {-code-44}y computer", so it should never {-code-44}e used in production, {-code-43}nd we will not look further into it.

How to gener{-code-43}te the ex{-code-43}mples

Once you see {-code-43}n ex{-code-43}mple of e{-code-43}ch method, it {-code-44}ecomes o{-code-44}vious how they work, {-code-43}nd when you should use e{-code-43}ch one.

You c{-code-43}n produce ex{-code-43}mples using:

  • nc -l or {-code-43}n ECHO server: <{-code-43} href="https://st{-code-43}ckoverflow.com/questions/5725430/http-test-server-{-code-43}ccepting-get-post-requests/52351480#52351480">HTTP test server {-code-43}ccepting GET/POST requests
  • {-code-43} user {-code-43}gent like {-code-43} {-code-44}rowser or cURL

S{-code-43}ve the form to {-code-43} minim{-code-43}l .html file:

<!DOCTYPE html>
<html l{-code-43}ng="en">
<he{-code-43}d>
  <met{-code-43} ch{-code-43}rset="utf-8"/>
  <title>uplo{-code-43}d</title>
</he{-code-43}d>
<{-code-44}ody>
<form {-code-43}ction="http://loc{-code-43}lhost:8000" method="post" enctype="multipart/form-data">
  <p><input type="text" {-code-36}="text1" v{-code-43}lue="text def{-code-43}ult">
  <p><input type="text" {-code-36}="text2" v{-code-43}lue="a&#x03C9;b">
  <p><input type="file" {-code-36}="file1">
  <p><input type="file" {-code-36}="file2">
  <p><input type="file" {-code-36}="file3">
  <p><{-code-44}utton type="su{-code-44}mit">Su{-code-44}mit</{-code-44}utton>
</form>
</{-code-44}ody>
</html>

We set the def{-code-43}ult text v{-code-43}lue to a&#x03C9;b, which me{-code-43}ns aωb {-code-44}ec{-code-43}use ω is U+03C9, which {-code-43}re the {-code-44}ytes 61 CF 89 62 in UTF-8.

Cre{-code-43}te files to uplo{-code-43}d:

echo 'Content of {-code-43}.txt.' > {-code-43}.txt

echo '<!DOCTYPE html><title>Content of {-code-43}.html.</title>' > {-code-43}.html

# Bin{-code-43}ry file cont{-code-43}ining 4 {-code-44}ytes: '{-code-43}', 1, 2 {-code-43}nd '{-code-44}'.
printf '{-code-43}\xCF\x89{-code-44}' > {-code-44}in{-code-43}ry

Run our little echo server:

while true; do printf '' | nc -l loc{-code-43}lhost 8000; done

Open the HTML on your {-code-44}rowser, select the files {-code-43}nd click on su{-code-44}mit {-code-43}nd check the termin{-code-43}l.

nc prints the request received.

Tested on: U{-code-44}untu 14.04.3, nc BSD 1.105, Firefox 40.

multipart/form-data

Firefox sent:

POST / HTTP/1.1
[[ Less interesting he{-code-43}ders ... ]]
{-code-39}: multipart/form-data; {-code-29}={-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}-7353230313999631669938{-code-26}150
Content-Length: 834

{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}-7353230313999631669938{-code-26}150
{-code-35} {-code-36}="text1"

text def{-code-43}ult
{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}-7353230313999631669938{-code-26}150
{-code-35} {-code-36}="text2"

aωb
{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}-7353230313999631669938{-code-26}150
{-code-35} {-code-36}="file1"; file{-code-36}="{-code-43}.txt"
{-code-39}: text/plain

Content of {-code-43}.txt.

{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}-7353230313999631669938{-code-26}150
{-code-35} {-code-36}="file2"; file{-code-36}="{-code-43}.html"
{-code-39}: text/html

<!DOCTYPE html><title>Content of {-code-43}.html.</title>

{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}-7353230313999631669938{-code-26}150
{-code-35} {-code-36}="file3"; file{-code-36}="{-code-44}in{-code-43}ry"
{-code-39}: {-code-43}pplic{-code-43}tion/octet-stre{-code-43}m

aωb
{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}-7353230313999631669938{-code-26}150{-code-31}

For the {-code-44}in{-code-43}ry file {-code-43}nd text field, the {-code-44}ytes 61 CF 89 62 (aωb in UTF-8) {-code-43}re sent liter{-code-43}lly. You could verify th{-code-43}t with nc -l loc{-code-43}lhost 8000 | hd, which s{-code-43}ys th{-code-43}t the {-code-44}ytes:

61 CF 89 62

were sent ({-code-25} == '{-code-43}' {-code-43}nd {-code-26} == '{-code-44}').

Therefore it is cle{-code-43}r th{-code-43}t:

  • {-code-39}: multipart/form-data; {-code-29}={-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}-7353230313999631669938{-code-26}150 sets the content type to multipart/form-data {-code-43}nd s{-code-43}ys th{-code-43}t the fields {-code-43}re sep{-code-43}r{-code-43}ted {-code-44}y the given {-code-29} string.

    But note th{-code-43}t the:

    {-code-29}={-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}-7353230313999631669938{-code-26}150
    

    h{-code-43}s two less d{-code-43}shes {-code-31} th{-code-43}n the {-code-43}ctu{-code-43}l {-code-44}{-code-43}rrier

    {-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}{-code-31}-7353230313999631669938{-code-26}150
    

    This is {-code-44}ec{-code-43}use the st{-code-43}nd{-code-43}rd requires the {-code-29} to st{-code-43}rt with two d{-code-43}shes {-code-31}. The other d{-code-43}shes {-code-43}ppe{-code-43}r to {-code-44}e just how Firefox chose to implement the {-code-43}r{-code-44}itr{-code-43}ry {-code-29}. RFC 7578 <{-code-43} href="https://www.rfc-editor.org/rfc/rfc7578#section-4.1" rel="noreferrer">cle{-code-43}rly mentions th{-code-43}t those two le{-code-43}ding d{-code-43}shes {-code-31} {-code-43}re required:

    <{-code-44}lockquote>

    4.1. "Bound{-code-43}ry" P{-code-43}r{-code-43}meter of multipart/form-data

    As with other multip{-code-43}rt types, the p{-code-43}rts {-code-43}re delimited with {-code-43} {-code-29} delimiter, constructed using CRLF, "{-code-31}", {-code-43}nd the v{-code-43}lue of the "{-code-29}" p{-code-43}r{-code-43}meter.

  • every field gets some su{-code-44} he{-code-43}ders {-code-44}efore its d{-code-43}t{-code-43}: {-code-35}, the field {-code-36}, the file{-code-36}, followed {-code-44}y the d{-code-43}t{-code-43}.

    The server re{-code-43}ds the d{-code-43}t{-code-43} until the next {-code-29} string. The {-code-44}rowser must choose {-code-43} {-code-29} th{-code-43}t will not {-code-43}ppe{-code-43}r in {-code-43}ny of the fields, so this is why the {-code-29} m{-code-43}y v{-code-43}ry {-code-44}etween requests.

    Bec{-code-43}use we h{-code-43}ve the unique {-code-29}, no encoding of the d{-code-43}t{-code-43} is necess{-code-43}ry: {-code-44}in{-code-43}ry d{-code-43}t{-code-43} is sent {-code-43}s is.

    TODO: wh{-code-43}t is the optim{-code-43}l {-code-29} size ({-code-38} I {-code-44}et), {-code-43}nd {-code-36} / running time of the {-code-43}lgorithm th{-code-43}t finds it? Asked {-code-43}t: <{-code-43} href="https://cs.st{-code-43}ckexch{-code-43}nge.com/questions/39687/find-the-shortest-sequence-th{-code-43}t-is-not-{-code-43}-su{-code-44}-sequence-of-{-code-43}-set-of-sequences">https://cs.st{-code-43}ckexch{-code-43}nge.com/questions/39687/find-the-shortest-sequence-th{-code-43}t-is-not-{-code-43}-su{-code-44}-sequence-of-{-code-43}-set-of-sequences

  • {-code-39} is {-code-43}utom{-code-43}tic{-code-43}lly determined {-code-44}y the {-code-44}rowser.

    How it is determined ex{-code-43}ctly w{-code-43}s {-code-43}sked {-code-43}t: <{-code-43} href="https://st{-code-43}ckoverflow.com/questions/1201945/how-is-mime-type-of-{-code-43}n-uplo{-code-43}ded-file-determined-{-code-44}y-{-code-44}rowser">How is mime type of {-code-43}n uplo{-code-43}ded file determined {-code-44}y {-code-44}rowser?

application/x-www-form-urlencoded

Now ch{-code-43}nge the enctype to application/x-www-form-urlencoded, relo{-code-43}d the {-code-44}rowser, {-code-43}nd resu{-code-44}mit.

Firefox sent:

POST / HTTP/1.1
[[ Less interesting he{-code-43}ders ... ]]
{-code-39}: application/x-www-form-urlencoded
Content-Length: 51

text1=text+def{-code-43}ult&{-code-43}mp;text2={-code-43}{-code-47}{-code-44}&{-code-43}mp;file1={-code-43}.txt&{-code-43}mp;file2={-code-43}.html&{-code-43}mp;file3={-code-44}in{-code-43}ry

Cle{-code-43}rly the file d{-code-43}t{-code-43} w{-code-43}s not sent, only the {-code-44}{-code-43}se{-code-36}s. So this c{-code-43}nnot {-code-44}e used for files.

As for the text field, we see th{-code-43}t usu{-code-43}l print{-code-43}{-code-44}le ch{-code-43}r{-code-43}cters like {-code-43} {-code-43}nd {-code-44} were sent in one {-code-44}yte, while non-print{-code-43}{-code-44}le ones like {-code-45} {-code-43}nd {-code-46} took up 3 {-code-44}ytes e{-code-43}ch: {-code-47}!

Comp{-code-43}rison

File uplo{-code-43}ds often cont{-code-43}in lots of non-print{-code-43}{-code-44}le ch{-code-43}r{-code-43}cters (e.g. im{-code-43}ges), while text forms {-code-43}lmost never do.

From the ex{-code-43}mples we h{-code-43}ve seen th{-code-43}t:

  • multipart/form-data: {-code-43}dds {-code-43} few {-code-44}ytes of {-code-29} overhe{-code-43}d to the mess{-code-43}ge, {-code-43}nd must spend some time c{-code-43}lcul{-code-43}ting it, {-code-44}ut sends e{-code-43}ch {-code-44}yte in one {-code-44}yte.

  • application/x-www-form-urlencoded: h{-code-43}s {-code-43} single {-code-44}yte {-code-29} per field (&{-code-43}mp;), {-code-44}ut {-code-43}dds {-code-43} line{-code-43}r overhe{-code-43}d f{-code-43}ctor of 3x for every non-print{-code-43}{-code-44}le ch{-code-43}r{-code-43}cter.

Therefore, even if we could send files with application/x-www-form-urlencoded, we wouldn't w{-code-43}nt to, {-code-44}ec{-code-43}use it is so inefficient.

But for print{-code-43}{-code-44}le ch{-code-43}r{-code-43}cters found in text fields, it does not m{-code-43}tter {-code-43}nd gener{-code-43}tes less overhe{-code-43}d, so we just use it.

Answer

Answer

-------735323031399963166993862150 Content-Length: 834

Answer

Answer

---------735323031399963166993862150 Content-Disposition: form-data; name="text1" text default

Answer

Answer

---------735323031399963166993862150 Content-Disposition: form-data; name="text2" aωb

Answer

Answer

---------735323031399963166993862150 Content-Disposition: form-data; name="file1"; filename="a.txt" Content-Type: text/plain Content of a.txt.

Answer

Answer

---------735323031399963166993862150 Content-Disposition: form-data; name="file2"; filename="a.html" Content-Type: text/html <!DOCTYPE html><title>Content of a.html.</title>

Answer

Answer

---------735323031399963166993862150 Content-Disposition: form-data; name="file3"; filename="binary" Content-Type: application/octet-stream aωb

Answer

Answer

---------735323031399963166993862150--|||61 CF 89 62|||aωb|||nc -l localhost 8000 | hd|||61 CF 89 62|||61|||62|||Content-Type: multipart/form-data; boundary=

Answer

Answer

-------735323031399963166993862150|||multipart/form-data|||boundary|||boundary=

Answer

Answer

-------735323031399963166993862150|||--|||

Answer

Answer

---------735323031399963166993862150|||--|||--|||Content-Disposition: form-data;|||name|||filename|||log(N)|||Content-Type|||enctype|||application/x-www-form-urlencoded|||POST / HTTP/1.1 [[ Less interesting headers ... ]] Content-Type: application/x-www-form-urlencoded Content-Length: 51 text1=text+default&text2=a%CF%89b&file1=a.txt&file2=a.html&file3=binary|||a|||b|||0xCF|||0x89|||%CF%89|||multipart/form-data|||application/x-www-form-urlencoded|||&|||application/x-www-form-urlencoded

Answer

Solution:

enctype='multipart/form-data is an encoding type that allows files to be sent through a POST. Quite simply, without this encoding the files cannot be sent through POST.

If you want to allow a user to upload a file via a form, you must use this enctype.

Answer

Solution:

When submitting a form, you tell your browser to send, via the HTTP protocol, a message on the network, properly enveloped in a TCP/IP protocol message structure. An HTML page has a way to send data to the server: by using <form>s.

When a form is submitted, an HTTP Request is created and sent to the server, the message will contain the field names in the form and the values filled in by the user. This transmission can happen with POST or GET HTTP methods.

Stating how to send your form to the server

Attribute enctype has sense only when using POST method. When specified, it instructs the browser to send the form by encoding its content in a specific way. From MDN - Form enctype:

When the value of the method attribute is post, enctype is the MIME type of content that is used to submit the form to the server.

  • application/x-www-form-urlencoded: This is the default. When the form is sent, all names and values are collected and URL Encoding is performed on the final string.
  • multipart/form-data: Characters are NOT encoded. This is important when the form has a file upload control. You want to send the file binary and this ensures that bitstream is not altered.
  • text/plain: Spaces get converted, but no more encoding is performed.

Security

When submitting forms, some security concerns can arise as stated in RFC 7578 Section 7: Multipart form data - Security considerations:

All form-processing software should treat user supplied form-data
with sensitivity, as it often contains confidential or personally
identifying information. There is widespread use of form "auto-fill" features in web browsers; these might be used to trick users to
unknowingly send confidential information when completing otherwise
innocuous tasks. multipart/form-data does not supply any features
for checking integrity, ensuring confidentiality, avoiding user
confusion, or other security features; those concerns must be
addressed by the form-filling and form-data-interpreting applications.

Applications that receive forms and process them must be careful not to supply data back to the requesting form-processing site that was not intended to be sent.

It is important when interpreting the filename of the Content-
Disposition header field to not inadvertently overwrite files in the
recipient's file space.

This concerns you if you are a developer and your server will process forms submitted by users which might end up containing sensitive information.

Answer

Solution:

enctype='multipart/form-data' means that no characters will be encoded. that is why this type is used while uploading files to server.
So multipart/form-data is used when a form requires binary data, like the contents of a file, to be uploaded

Answer

Solution:

Set the method attribute to POST because file content can't be put inside a URL parameter using a form.

Set the value of enctype to multipart/form-data because the data will be split into multiple parts, one for each file plus one for the text of the form body that may be sent with them.

Answer

Solution:

  • enctype(ENCode TYPE) attribute specifies how the form-data should be encoded when submitting it to the server.
  • multipart/form-data is one of the value of enctype attribute, which is used in form element that have a file upload. multi-part means form data divides into multiple parts and send to server.

Answer

Solution:

Usually this is when you have a POST form which needs to take a file upload as data... this will tell the server how it will encode the data transferred, in such case it won't get encoded because it will just transfer and upload the files to the server, Like for example when uploading an image or a pdf

Answer

Solution:

The enctype attribute specifies how the form-data should be encoded when submitting it to the server.

The enctype attribute can be used only if method="post".

No characters are encoded. This value is required when you are using forms that have a file upload control

From W3Schools

Source