Form Data Encoding Roundup

In an HTML form element, the enctype attribute specifies how the data will be encoded when it is POSTed to the web server. Traditionally, there are two accepted content types for HTML forms:

But there is nothing to stop someone from specifying whatever enctype value that they want (e.g., "application/x-foo"). Of course specifying your own random value doesn't mean that the browser will understand how to submit it or the web server will understand how to process it.

The following lists how some popular browsers respond to unexpected but technically valid enctype values. Each of the MIME types from this list was tested. The following browsers were tested:

Go straight to the conclusions. Or, try some samples yourself.

Safari - Mac OS X

Version Tested: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/419.3 (KHTML, like Gecko) Safari/419.3

Safari submits the following content types:

The following rules are applied based on the value of enctype:

Specified enctypeSubmitted Content-TypeSample
(omitted)application/x-www-form-urlencoded(omitted)
application/x-www-form-urlencodedapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded
multipart/form-datamultipart/form-datamultipart/form-data
contains the word multipartmultipart/form-datamultipart/example
contains the word form-datamultipart/form-dataexample/form-data
contains the word texttext/plain (content-type specifies nonexistent MIME boundary and posted data is urlencoded)text/example
contains the word plaintext/plain (content-type specifies nonexistent MIME boundary and posted data is urlencoded)example/plain
anything elseapplication/x-www-form-urlencodedexample/example
top

Safari - Windows

Version Tested: Mozilla/5.0 (Windows; U; Windows NT 5.1; en) AppleWebKit/522.15.5 (KHTML, like Gecko) Version/3.0.3 Safari/522.15.5

Safari submits the following content types:

The following rules are applied based on the value of enctype:

Specified enctypeSubmitted Content-TypeSample
(omitted)application/x-www-form-urlencoded(omitted)
application/x-www-form-urlencodedapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded
multipart/form-datamultipart/form-datamultipart/form-data
contains the word multipartmultipart/form-datamultipart/example
contains the word form-datamultipart/form-dataexample/form-data
contains the word texttext/plain (content-type specifies empty MIME boundary and posted data is urlencoded)text/example
contains the word plaintext/plain (content-type specifies empty MIME boundary and posted data is urlencoded)example/plain
anything elseapplication/x-www-form-urlencodedexample/example
top

Konqueror - Linux

Version Tested: Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.7 (like Gecko)

Konqueror submits the following content types:

The following rules are applied based on the value of enctype:

Specified enctypeSubmitted Content-TypeSample
(omitted)application/x-www-form-urlencoded(omitted)
application/x-www-form-urlencodedapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded
multipart/form-datamultipart/form-datamultipart/form-data
contains the word multipartmultipart/form-datamultipart/example
contains the word form-datamultipart/form-dataexample/form-data
contains the word texttext/plain (content-type specifies nonexistent MIME boundary and posted data is urlencoded)text/example
contains the word plaintext/plain (content-type specifies nonexistent MIME boundary and posted data is urlencoded)example/plain
anything elseapplication/x-www-form-urlencodedexample/example
top

Mozilla Firefox - Mac OS X

Version Tested: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7

Opera submits the following content types:

The following rules are applied based on the value of enctype:

Specified enctypeSubmitted Content-TypeSample
(omitted)application/x-www-form-urlencoded(omitted)
application/x-www-form-urlencodedapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded
multipart/form-datamultipart/form-datamultipart/form-data
text/plaintext/plaintext/plain
anything elseapplication/x-www-form-urlencodedexample/example
top

Mozilla Firefox - Windows

Version Tested: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7

Opera submits the following content types:

The following rules are applied based on the value of enctype:

Specified enctypeSubmitted Content-TypeSample
(omitted)application/x-www-form-urlencoded(omitted)
application/x-www-form-urlencodedapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded
multipart/form-datamultipart/form-datamultipart/form-data
text/plaintext/plaintext/plain
anything elseapplication/x-www-form-urlencodedexample/example
top

Mozilla Firefox - Linux

Version Tested: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7

Opera submits the following content types:

The following rules are applied based on the value of enctype:

Specified enctypeSubmitted Content-TypeSample
(omitted)application/x-www-form-urlencoded(omitted)
application/x-www-form-urlencodedapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded
multipart/form-datamultipart/form-datamultipart/form-data
text/plaintext/plaintext/plain
anything elseapplication/x-www-form-urlencodedexample/example
top

Opera - Mac OS X

Version Tested: Opera/9.23 (Macintosh; PPC Mac OS X; U; en)

Opera submits the following content types:

The following rules are applied based on the value of enctype:

Specified enctypeSubmitted Content-TypeSample
(omitted)application/x-www-form-urlencoded(omitted)
application/x-www-form-urlencodedapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded
multipart/form-datamultipart/form-datamultipart/form-data
text/plaintext/plaintext/plain
anything elseapplication/x-www-form-urlencodedexample/example
top

Opera - Windows

Version Tested: Opera/9.23 (Windows NT 5.1; U; en)

Opera submits the following content types:

The following rules are applied based on the value of enctype:

Specified enctypeSubmitted Content-TypeSample
(omitted)application/x-www-form-urlencoded(omitted)
application/x-www-form-urlencodedapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded
multipart/form-datamultipart/form-datamultipart/form-data
text/plaintext/plaintext/plain
anything elseapplication/x-www-form-urlencodedexample/example
top

Opera - Linux

Version Tested: Opera/9.23 (X11; Linux i686; U; en)

Opera submits the following content types:

The following rules are applied based on the value of enctype:

Specified enctypeSubmitted Content-TypeSample
(omitted)application/x-www-form-urlencoded(omitted)
application/x-www-form-urlencodedapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded
multipart/form-datamultipart/form-datamultipart/form-data
text/plaintext/plaintext/plain
anything elseapplication/x-www-form-urlencodedexample/example
top

Internet Explorer 7 - Windows

Version Tested: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322)

IE submits the following content types:

The following rules are applied based on the value of enctype:

Specified enctypeSubmitted Content-TypeSample
(omitted)application/x-www-form-urlencoded(omitted)
application/x-www-form-urlencodedapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded
multipart/form-datamultipart/form-datamultipart/form-data
text/plaintext/plaintext/plain
anything elseapplication/x-www-form-urlencodedexample/example
top

Internet Explorer 6 - Windows

Version Tested: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)

IE submits the following content types:

The following rules are applied based on the value of enctype:

Specified enctypeSubmitted Content-TypeSample
(omitted)application/x-www-form-urlencoded(omitted)
application/x-www-form-urlencodedapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded
multipart/form-datamultipart/form-datamultipart/form-data
text/plaintext/plaintext/plain
anything elseapplication/x-www-form-urlencodedexample/example
top

Internet Explorer 5 - Mac OS X

Version Tested:

IE submits the following content types:

The following rules are applied based on the value of enctype:

Specified enctypeSubmitted Content-TypeSample
(omitted)application/x-www-form-urlencoded(omitted)
application/x-www-form-urlencodedapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded
multipart/form-datamultipart/form-datamultipart/form-data
anything elseapplication/x-www-form-urlencodedexample/example
top

Conclusions

As expected, all of the browsers properly support 'application/x-www-form-urlencoded' and 'multipart/form-data' content-type values for the form element's enctype attribute. Additionally, Microsoft Internet Explorer (versions 6 and 7), Mozilla Firefox and Opera support a content-type value of 'text/plain'. The form values are submitted without any encoding or MIME boundary.

Safari and Konqueror exhibit the most idiosyncratic behavior. Both apply a heuristic to determine the proper content-type based on the enctype value by checking for the strings "multipart", "form-data", "text" and "plain". Any enctype that contains "multipart" or "form-data" is treated as 'multipart/form-data'. If "text" or "plain" are found, then the content-type is set to 'text/plain' but the form contents are still urlencoded. An examination of the source code shows the origins of the behavior.

From the KDE source, "kdelibs/khtml/html/html_formimpl.cpp" contains the following:


void HTMLFormElementImpl::setEnctype( const DOMString& type )
{
    if(type.string().indexOf("multipart", 0, Qt::CaseInsensitive) != -1 || type.string().indexOf("form-data", 0, Qt::CaseInsensitive) != -1)
    {
        m_enctype = "multipart/form-data";
        m_multipart = true;
        m_post = true;
    } else if (type.string().indexOf("text", 0, Qt::CaseInsensitive) != -1 || type.string().indexOf("plain", 0, Qt::CaseInsensitive) != -1)
    {
        m_enctype = "text/plain";
        m_multipart = false;
    }
    else
    {
        m_enctype = "application/x-www-form-urlencoded";
        m_multipart = false;
    }
    m_encCharset.clear();
}
      

And from "kdelibs/khtml/khtml_part.cpp":


    // construct some user headers if necessary
    if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
      browserArgs.setContentType( "Content-Type: application/x-www-form-urlencoded" );
    else // contentType must be "multipart/form-data"
      browserArgs.setContentType( "Content-Type: " + contentType + "; boundary=" + boundary );
      

From the WebKit source, "WebCore/html/HTMLFormElement.cpp" contains:


void HTMLFormElement::parseEnctype(const String& type)
{
    if(type.contains("multipart", false) || type.contains("form-data", false)) {
        m_enctype = "multipart/form-data";
        m_multipart = true;
    } else if (type.contains("text", false) || type.contains("plain", false)) {
        m_enctype = "text/plain";
        m_multipart = false;
    } else {
        m_enctype = "application/x-www-form-urlencoded";
        m_multipart = false;
    }
}
      

And from "WebCore/loader/FrameLoader.cpp":


        // construct some user headers if necessary
        if (contentType.isNull() || contentType == "application/x-www-form-urlencoded")
            frameRequest.resourceRequest().setHTTPContentType(contentType);
        else // contentType must be "multipart/form-data"
            frameRequest.resourceRequest().setHTTPContentType(contentType + "; boundary=" + boundary);
      

Further Research

The form element also supports an accept-charset attribute. Additional research may be warranted to determine if different values affect how the data content is encoded and submitted.

Source Scripts

The following scripts were used. There are provided in the hope that they may be useful for someone: