在Firefox上,FormData()对象不会从表单添加提交类型输入

481*_*caf 9 javascript forms firefox xmlhttprequest form-data

今天我遇到了一个有趣的bug,花了很多时间才到达底部.

设置

页面上的表单.在提交时,将捕获数据并new FormData()使用它创建对象.

该对象与脚本一起发送并xhr请求.php,然后脚本返回ok/ error消息.

代码看起来像这样:( 简化版,不需要绒毛)

<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>
Run Code Online (Sandbox Code Playgroud)

发送.php它将导致数组看起来像这样:

Array
(
    [name] => some name
    [email] => some email
    [phone] => 11111111
    [website] => some site
    [details] => some details
    [send] => Send
)
Run Code Online (Sandbox Code Playgroud)

并且.php将响应要么{"message":"ok","code":0}{"message":"error","code":1}

现在这是预期的行为.这是我在Chrome,IE或Safari上获得的.

问题

但是在Firefox上,除了没有submitinput(name="send")键/值对,我得到相同的数组:

Array
(
    [name] => some name
    [email] => some email
    [phone] => 11111111
    [website] => some site
    [details] => some details
)
Run Code Online (Sandbox Code Playgroud)

我尝试了Linux和Windows,以覆盖我的基础,但它仍然给出了同样令人不满意的结果.

在网上搜索并空出来后,我解决它的方式(更多的修补,而不是真正解决)是覆盖send键/值:

var data = new FormData(frm);
data.append('send', 'Send');
xhr.send(data);
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为如果它已经被定义(Chrome等等)它会被覆盖,如果它不存在,它就会被创建.

问题

  1. 类似的 - 你有没有遇到类似的事情?
  2. 修复 - 我认为我的解决方案是黑客攻击,你有什么想法可以更好地解决问题吗?

Bar*_*mar 7

根据WHATWG规范,FireFox似乎是正确的.

构造函数的XMLHttpRequest规范FormData说:

  1. 如果form给出,则将fd条目设置构造表单数据集的结果form.

然后在构造表单数据集的描述中,它说:

可选地在提交者提交者的上下文中为表单表单构造表单数据集的算法如下.如果没有另外指定,则提交者为空.

如果表单中的按钮是提交者,则它只包含在表单数据集中.但是当从FormData构造函数执行此算法时,没有指定提交者,因此表单数据集中不应包含任何按钮.