Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
246 views
in Technique[技术] by (71.8m points)

javascript - FormData() object does not add submit-type inputs from form, while on Firefox

Today I came across an interesting bug, which took a good chunk of time to get to the bottom of.

The setup

A form on a page. On submit, the data gets captured and new FormData() object gets created with it.

That object gets sent with and xhr request to an .php script, which then returns an ok / error message.

The code looks something like this: (simplified version, no need for fluff)

<form name="frm" id="frm" action="" method="post" onsubmit="save(event, this);" enctype="multipart/form-data">
    <input name="name" id="name" type="text" value="..." />
    <input name="email" id="email" type="text" value="..." />
    <input name="phone" id="phone" type="text" value="..." />
    <input name="website" id="website" type="text" value="..." />
    <textarea name="details" id="details"></textarea>
    <input name="send" type="submit" value="Send" />
</form>

<script type="text/javascript">

function save(e, frm) {

        if (document.getElementById('nume').value == '' ||
          document.getElementById('email').value == '' ||
          document.getElementById('telefon').value == '' ||
          document.getElementById('site').value == '') {

            alert('Forms empty');

        } else {

            var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');

            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {

                    var r = JSON.parse(xhr.responseText);

                    if (r.code == 0) {
                        document.getElementById('message_ok').style.display = 'block';
                    } else {
                        document.getElementById('message_err').style.display = 'block';
                    }
                }
            };

            xhr.open('POST', 'http://url', true);
            var data = new FormData(frm);
            xhr.send(data);

        }
    e.preventDefault();
}

</script>

Sending this to .php will result in an array which kind of looks like this:

Array
(
    [name] => some name
    [email] => some email
    [phone] => 11111111
    [website] => some site
    [details] => some details
    [send] => Send
)

and .php will respond with either {"message":"ok","code":0} or {"message":"error","code":1}

Now this is the expected behavior. This is what I get on either Chrome, IE or Safari.

The problem

On Firefox however, I get the same array except without the submit input (name="send") key/value pair:

Array
(
    [name] => some name
    [email] => some email
    [phone] => 11111111
    [website] => some site
    [details] => some details
)

I tried on both Linux and Windows, to cover my basis, yet it still gave the same unsatisfying result.

Solution

After searching online and coming up empty, the way I solved it (more of patching, not really solving) was to overwrite the send key/value:

var data = new FormData(frm);
data.append('send', 'Send');
xhr.send(data);

This works, because if it's already defined (Chrome, etc...) it gets overwritten, if it doesn't exist, it gets created.

Questions

  1. Similar - Have you ever faced something similar?
  2. Fix - I consider my solution a hack, have you got any ideas for a better fix?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

FireFox seems to be correct, according to the WHATWG specification.

The XMLHttpRequest specification of the FormData constructor says:

  1. If form is given, set fd's entries to the result of constructing the form data set for form.

Then in the description of constructing the form data set, it says:

The algorithm to construct the form data set for a form form optionally in the context of a submitter submitter is as follows. If not specified otherwise, submitter is null.

A button in the form is only included in the form data set if it's the submitter. But when this algorithm is executed from the FormData constructor, no submitter is specified, so no buttons should be included in the form data set.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...