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

时间:2016-07-09 03:11:15

标签: javascript forms firefox xmlhttprequest form-data

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

设置

页面上的表单。提交时,将捕获数据并使用它创建ImportError: No module named 'blog' 对象。

该对象通过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> 将导致数组看起来像这样:

.php

Array ( [name] => some name [email] => some email [phone] => 11111111 [website] => some site [details] => some details [send] => Send ) 会回复.php{"message":"ok","code":0}

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

问题

在Firefox上,除了没有{"message":"error","code":1}输入(submit)键/值对之外,我得到相同的数组:

name="send"

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

解决方案

在网上搜索并空出来后,我解决它的方式(更多修补,而不是真正解决)是覆盖Array ( [name] => some name [email] => some email [phone] => 11111111 [website] => some site [details] => some details ) 键/值:

send

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

问题

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

3 个答案:

答案 0 :(得分:7)

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

FormData构造函数的XMLHttpRequest规范说:

  
      
  1. 如果出现form,请将fd的条目设置为form constructing the form data set的结果。
  2.   

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

  

为表单表单构建表单数据集的算法可选地在提交者提交者的上下文中,如下所示。如果没有另外指定, submitter 为空。

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

答案 1 :(得分:2)

在Chrome 58中遇到类似的事情。

在我的问题中,有多个提交按钮,我需要知道选择了哪一个,或者至少是否选择了特定的按钮。

我可怕的黑客是明确地监听被选中的按钮,创建一个隐藏的输入并在提交按钮之前插入它。

更新:改进黑客

听取提交按钮的点击并通过按钮作为提交者发送到on('submit'),并在ajax调用中使用之前附加到FormData对象。

修改输入[type =“submit”]的味道,并可能对submitter的内容进行额外的错误检查。

$('#defaultModalObject-1').on('click', 'button[type="submit"]', function(event) {
    /* horrible hack to detect wizard_goto_step submissions via ajax */
    event.preventDefault();
    $(event.target.form).trigger('submit', event.target);
});

$('#defaultModalObject-1').on('submit', 'form', function(event, submitter){
    ...
    var formdata = new FormData(form[0]);

    if (submitter != undefined) {
        formdata.append(submitter.name, submitter.value);
    }
    ...
});

Original Hack

$('#ajax_form_modal_result').on('click', 'button[type="submit"][name="wizard_goto_step"]', function(event) {
    /* horrible hack to detect wizard_goto_step submissions via ajax */
    event.preventDefault();
    var input = $('input[type="hidden"]').attr('name', 'wizard_goto_step').val(event.target.value);
    $(event.target).before(input);
    $(event.target.form).trigger('submit');
});

不幸的是,我的委托表单处理程序$('#defaultModalObject-1').on('submit', 'form', function(event) { ... });

上没有创建者信息

答案 2 :(得分:1)

我们在Linux客户端上遇到同样的问题,并使用下面的代码将所有按钮元素添加到我们的formdata中。

第一个问题是在某些代码中获取表单数据时出错

if($this.is('form'))
{
  var fd = new FormData($this.get(0));
}
else
{
  var fd = new FormData();
}

第二个问题就像是以ajax形式添加按钮的问题。有时我们在一个表单中有多个按钮,并且想要检测哪一个被按下。

$this.find('button').each(function()
{
  fd.append(this.getAttribute('name'), this.value);
});

如果有人需要使用输入类型提交可以像上面的代码一样添加,我们在这个条件下使用按钮:)