Internet Explorer 11 breaks empty <input> elements on POST if Javascript is used against them in the DOM first

My question is simple, even if the description of the problem takes up the rest of this post - is this IE behavior described below, a known bug, by design, or just "one of those things" we should know and code?

Edit: Or is it all in my own environment for some reason, per @James comment?

Problem Statement

When there are multiple elements in a form <input type='file'>

, if some of the elements input

are left blank and Javascript does not work on the elementsinput

, each element is sent back to POST

as part of the plural-form delimited data , including blank elements , in the order displayed on the page. This is expected behavior.

If there is Javascript that interacts with the elements input

(for example, validates them), Chrome and Firefox will still send back all the elements, whether they have values ​​or not. This is expected behavior as well. However, if empty elements are input

"reset" after simply reading them into the DOM with Javascript, IE 11 will only send those elements input

that matter .

Below is a brief description of the number of multipart form elements submitted in each script by the browser:

Browser |   No    | JS, no  |   JS,
        |   JS    | "reset" | "reset"
--------+---------+---------+---------
IE 11   |    4    |    2    |    4
Firefox |    4    |    4    |    4
Chrome  |    4    |    4    |    4

      

Sample code

Consider the following 100% pure HTML and Javascript - all client-side, no CSS, jQuery or other fillers. Points to note:

  • The fields are wrapped in a form with three submit buttons (for our three test cases) that do everything POST

    back to the server.
  • Three submit buttons allow you to:
    • Submitting a form without Javascript.
    • Submitting a form using Javascript, iterating over the elements input

      but doing nothing for them (which still causes interesting bug behavior in IE), I split it into this very simple case, but it gets run in code much harder than shown).
    • Submitting a form using Javascript that "flushes" empty elements input

      , causing empty ones to flow from IE to POST

      again.
  • There are four elements <input type='file'>

    that allow us to leave some blanks.

This is not optimal code, but I think it shows what I am talking about as simply as possible.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Page 1</title>
</head>
<body>
    <form action="/Default/Details/1" enctype="multipart/form-data" id="fileForm" method="post">
        <dl>
            <dt><label for="fileinput1">File input 1</label></dt>
            <dd>
                <input type="file" name="files" id="fileinput1" />
            </dd>
        </dl>
        <dl>
            <dt><label for="fileinput2">File input 2</label></dt>
            <dd>
                <input type="file" name="files" id="fileinput2" />
            </dd>
        </dl>
        <dl>
            <dt><label for="fileinput3">File input 3</label></dt>
            <dd>
                <input type="file" name="files" id="fileinput3" />
            </dd>
        </dl>
        <dl>
            <dt><label for="fileinput4">File input 4</label></dt>
            <dd>
                <input type="file" name="files" id="fileinput4" />
            </dd>
        </dl>
        <div class="col-md-offset-1 col-md-10">
            <input id="submitButton" type="submit" value="No Javascript, no worries" />
            <input id="submitButton" type="submit" value="IE strips empty fields" onclick="ValidateForm();" />
            <input id="submitButton" type="submit" value="We put them back" onclick="ValidateForm2();" />
        </div>
        <script>
            function ValidateForm() {
                var inputs = document.getElementsByTagName('input');

                for (var i = 0; i < inputs.length; i++) {
                    // For each file input, check to see if it has a file (each input element can select multiple files,
                    // only look for first file in each input element).
                    if (inputs[i]['type'] == 'file' && inputs[i].files && inputs[i].files[0] && inputs[i].files[0].size) {
                        // Do something or other like compare total file sizes to max request size...
                    }
                }

                return true;
            }

            function ValidateForm2() {
                var inputs = document.getElementsByTagName('input');

                for (var i = 0; i < inputs.length; i++) {
                    // For each file input, check to see if it has a file (each input element can select multiple files,
                    // only look for first file in each input element).
                    if (inputs[i]['type'] == 'file' && inputs[i].files && inputs[i].files[0] && inputs[i].files[0].size) {
                        // Do something or other like compare total file sizes to max request size...
                    }
                    else if (inputs[i]['type'] == 'file') {
                        inputs[i].type = '';     // One of many ways to reset...
                        inputs[i].type = 'file'; // ...the empty file input control
                    }
                }

                return true;
            }
        </script>
    </form>
</body>
</html>

      

Expected behavior

I used Fiddler to capture various requests POST

returning from the browser to the test web application. Using IE and the first button as an example, this is what I think is the expected behavior (as it is most common in most situations in most browsers).

This test uses only the first and third file input fields to show the expected behavior for the second and fourth blank input fields.

There are four test files, Test1.txt

via Test4.txt

. Each contains something like " Test 1 file contents...

" for Test1.txt

(with the number changed for each file). This makes it easier to see the contents of the file in the next HTTP request POST

and in all tests at the end.

POST http://localhost:59545/Default/Details/1 HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Referer: http://localhost:59545/Page1.html
Accept-Language: en-US
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko
Content-Type: multipart/form-data; boundary=---------------------------7e11462140376
Accept-Encoding: gzip, deflate
Content-Length: 764
DNT: 1
Host: localhost:59545
Connection: Keep-Alive
Pragma: no-cache

-----------------------------7e11462140376
Content-Disposition: form-data; name="files"; filename="F:\Test1.txt"
Content-Type: text/plain

Test 1 file contents...
-----------------------------7e11462140376
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


-----------------------------7e11462140376
Content-Disposition: form-data; name="files"; filename="F:\Test3.txt"
Content-Type: text/plain

Test 3 file contents...
-----------------------------7e11462140376
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


-----------------------------7e11462140376--

      

Please note that there are four "slots" in the contents of multi-page forms, the first and the third are the contents Test1.txt

and Test3.txt

accordingly, the second and the fourth empty.

Problem behavior

When Javascript in IE (only) iterates through the elements input

(triggered by the second button), even if it does nothing for the elements , it removes the empty input

elements and only dispatches the first and third, for example:

POST http://localhost:59545/Default/Details/1 HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Referer: http://localhost:59545/Page1.html
Accept-Language: en-US
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko
Content-Type: multipart/form-data; boundary=---------------------------7e129ec140376
Accept-Encoding: gzip, deflate
Content-Length: 470
DNT: 1
Host: localhost:59545
Connection: Keep-Alive
Pragma: no-cache

-----------------------------7e129ec140376
Content-Disposition: form-data; name="files"; filename="F:\Test1.txt"
Content-Type: text/plain

Test 1 file contents...
-----------------------------7e129ec140376
Content-Disposition: form-data; name="files"; filename="F:\Test3.txt"
Content-Type: text/plain

Test 3 file contents...
-----------------------------7e129ec140376--

      

Environment

Windows Server 2016 updated.

Browser options:

  • Internet Explorer 11 - 11.1480.14393.0 (update KB4025252)
  • Chrome - 59.0.3071.115
  • Firefox - 54.0.1

Appendix: Fiddler Trace Trace

Each test uses only the first and third file input fields to show the expected behavior for the second and fourth blank input fields.

There are four test files, Test1.txt

via Test4.txt

. Each contains something like " Test 1 file contents...

" for Test1.txt

(with the number changed for each file). This makes it easier to view the contents of the file in the HTTP request POST

.

Each of the three buttons was tested on IE, Firefox and Chrome in the following order:

  • "No Javascript, don't worry"
  • "IE removes empty fields"
  • "We will bring them back"

Internet Explorer 11

IE Test 1: No Javascript, No Problem Button

Four multipart form elements submitted POST

as expected.

POST http://localhost:59545/Default/Details/1 HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Referer: http://localhost:59545/Page1.html
Accept-Language: en-US
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko
Content-Type: multipart/form-data; boundary=---------------------------7e11462140376
Accept-Encoding: gzip, deflate
Content-Length: 764
DNT: 1
Host: localhost:59545
Connection: Keep-Alive
Pragma: no-cache

-----------------------------7e11462140376
Content-Disposition: form-data; name="files"; filename="F:\Test1.txt"
Content-Type: text/plain

Test 1 file contents...
-----------------------------7e11462140376
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


-----------------------------7e11462140376
Content-Disposition: form-data; name="files"; filename="F:\Test3.txt"
Content-Type: text/plain

Test 3 file contents...
-----------------------------7e11462140376
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


-----------------------------7e11462140376--

      

IE Test 2: "IE strips empty fields" button

Only two multipart form elements posted to POST

!

POST http://localhost:59545/Default/Details/1 HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Referer: http://localhost:59545/Page1.html
Accept-Language: en-US
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko
Content-Type: multipart/form-data; boundary=---------------------------7e129ec140376
Accept-Encoding: gzip, deflate
Content-Length: 470
DNT: 1
Host: localhost:59545
Connection: Keep-Alive
Pragma: no-cache

-----------------------------7e129ec140376
Content-Disposition: form-data; name="files"; filename="F:\Test1.txt"
Content-Type: text/plain

Test 1 file contents...
-----------------------------7e129ec140376
Content-Disposition: form-data; name="files"; filename="F:\Test3.txt"
Content-Type: text/plain

Test 3 file contents...
-----------------------------7e129ec140376--

      

IE 3 Test: "We'll Get Them Back" Button

Four multipart form elements submitted POST

as expected.

POST http://localhost:59545/Default/Details/1 HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Referer: http://localhost:59545/Page1.html
Accept-Language: en-US
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko
Content-Type: multipart/form-data; boundary=---------------------------7e12d917140376
Accept-Encoding: gzip, deflate
Content-Length: 769
DNT: 1
Host: localhost:59545
Connection: Keep-Alive
Pragma: no-cache

-----------------------------7e12d917140376
Content-Disposition: form-data; name="files"; filename="F:\Test1.txt"
Content-Type: text/plain

Test 1 file contents...
-----------------------------7e12d917140376
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


-----------------------------7e12d917140376
Content-Disposition: form-data; name="files"; filename="F:\Test3.txt"
Content-Type: text/plain

Test 3 file contents...
-----------------------------7e12d917140376
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


-----------------------------7e12d917140376--

      

Firefox

Firefox Test 1: No Javascript, No Problem Button

Four multipart form elements submitted POST

as expected.

POST http://localhost:59545/Default/Details/1 HTTP/1.1
Host: localhost:59545
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------225491224652
Content-Length: 665
Referer: http://localhost:59545/Page1.html
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

-----------------------------225491224652
Content-Disposition: form-data; name="files"; filename="Test1.txt"
Content-Type: text/plain

Test 1 file contents...
-----------------------------225491224652
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


-----------------------------225491224652
Content-Disposition: form-data; name="files"; filename="Test3.txt"
Content-Type: text/plain

Test 3 file contents...
-----------------------------225491224652
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


-----------------------------225491224652--

      

Firefox Test 2: IE strips empty fields button

Four multipart form elements submitted POST

as expected.

POST http://localhost:59545/Default/Details/1 HTTP/1.1
Host: localhost:59545
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------20141440714759
Content-Length: 675
Referer: http://localhost:59545/Page1.html
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

-----------------------------20141440714759
Content-Disposition: form-data; name="files"; filename="Test1.txt"
Content-Type: text/plain

Test 1 file contents...
-----------------------------20141440714759
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


-----------------------------20141440714759
Content-Disposition: form-data; name="files"; filename="Test3.txt"
Content-Type: text/plain

Test 3 file contents...
-----------------------------20141440714759
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


-----------------------------20141440714759--

      

Firefox Test 3: "We'll get them back" button

Four multipart form elements submitted POST

as expected.

POST http://localhost:59545/Default/Details/1 HTTP/1.1
Host: localhost:59545
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------16987275582373
Content-Length: 675
Referer: http://localhost:59545/Page1.html
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

-----------------------------16987275582373
Content-Disposition: form-data; name="files"; filename="Test1.txt"
Content-Type: text/plain

Test 1 file contents...
-----------------------------16987275582373
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


-----------------------------16987275582373
Content-Disposition: form-data; name="files"; filename="Test3.txt"
Content-Type: text/plain

Test 3 file contents...
-----------------------------16987275582373
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


-----------------------------16987275582373--

      

Chrome

Chrome Test 1: No Javascript, No Problem Button

Four multipart form elements submitted POST

as expected.

POST http://localhost:59545/Default/Details/1 HTTP/1.1
Host: localhost:59545
Connection: keep-alive
Content-Length: 660
Cache-Control: max-age=0
Origin: http://localhost:59545
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarysARPkT6Y1fHbw9sF
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://localhost:59545/Page1.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

------WebKitFormBoundarysARPkT6Y1fHbw9sF
Content-Disposition: form-data; name="files"; filename="Test1.txt"
Content-Type: text/plain

Test 1 file contents...
------WebKitFormBoundarysARPkT6Y1fHbw9sF
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundarysARPkT6Y1fHbw9sF
Content-Disposition: form-data; name="files"; filename="Test3.txt"
Content-Type: text/plain

Test 3 file contents...
------WebKitFormBoundarysARPkT6Y1fHbw9sF
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundarysARPkT6Y1fHbw9sF--

      

Chrome test 2: "IE strips empty fields" button

Four multipart form elements submitted POST

as expected.

POST http://localhost:59545/Default/Details/1 HTTP/1.1
Host: localhost:59545
Connection: keep-alive
Content-Length: 660
Cache-Control: max-age=0
Origin: http://localhost:59545
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryVYNZIw4uo5TwOmXG
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://localhost:59545/Page1.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

------WebKitFormBoundaryVYNZIw4uo5TwOmXG
Content-Disposition: form-data; name="files"; filename="Test1.txt"
Content-Type: text/plain

Test 1 file contents...
------WebKitFormBoundaryVYNZIw4uo5TwOmXG
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundaryVYNZIw4uo5TwOmXG
Content-Disposition: form-data; name="files"; filename="Test3.txt"
Content-Type: text/plain

Test 3 file contents...
------WebKitFormBoundaryVYNZIw4uo5TwOmXG
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundaryVYNZIw4uo5TwOmXG--

      

Chrome Test 3: "We'll bring them back" button

Four multipart form elements submitted POST

as expected.

POST http://localhost:59545/Default/Details/1 HTTP/1.1
Host: localhost:59545
Connection: keep-alive
Content-Length: 660
Cache-Control: max-age=0
Origin: http://localhost:59545
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryI6IuNQdTSMb21vHW
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://localhost:59545/Page1.html
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

------WebKitFormBoundaryI6IuNQdTSMb21vHW
Content-Disposition: form-data; name="files"; filename="Test1.txt"
Content-Type: text/plain

Test 1 file contents...
------WebKitFormBoundaryI6IuNQdTSMb21vHW
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundaryI6IuNQdTSMb21vHW
Content-Disposition: form-data; name="files"; filename="Test3.txt"
Content-Type: text/plain

Test 3 file contents...
------WebKitFormBoundaryI6IuNQdTSMb21vHW
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundaryI6IuNQdTSMb21vHW--

      

+3


source to share





All Articles