出现错误“由于未连接表单而取消了表单提交”


156

我有一个使用JQuery 1.7的旧网站,该网站在两天前都可以正常工作。突然我的某些按钮不再起作用,单击它们后,我在控制台中收到以下警告:

表单提交已取消,因为未连接表单

点击后的代码是这样的:

 this.handleExcelExporter = function(href, cols) {
   var form = $('<form method="post"><input type="submit" /><input type="hidden" name="layout" /></form>').attr('action', href);
   $('input[name="layout"]', form).val(JSON.stringify(cols));
   $('input[type="submit"]', form).click();
 }

Chrome 56似乎不再支持这种代码。是不是 如果是,我的问题是:

  1. 为什么这突然发生了?没有任何弃用警告?
  2. 此代码的解决方法是什么?
  3. 有没有一种方法可以强制chrome(或其他浏览器)像以前一样工作而不更改任何代码?

PS 在最新的firefox版本中也不起作用(没有任何消息)。另外,它在IE 11.0和Edge中也不起作用!(都没有任何消息)


我在接受的答案中添加了一个修复程序,以匹配表单是jQuery对象的事实。请注意,这还会影响jQuery .submit()处理程序(除了.click()上面指示的方法之外)。
ryanm

Answers:


185

快速解答:将表格附加到正文中。

document.body.appendChild(form);

或者,如果您如上所述使用jQuery: $(document.body).append(form);

详细信息:根据HTML标准,如果表单未与浏览上下文(文档)相关联,则表单提交将被中止。

HTML SPEC参见4.10.21.3.2

在Chrome 56中,应用了此规范。

Chrome代码差异请参阅@@ -347,9 +347,16 @@

PS关于您的问题#1。在我看来,与ajax不同,表单提交会导致页面立即移动。
因此,显示“已过时的警告消息”几乎是不可能的。
我也认为功能更改列表中未包含此重大更改是不可接受的。Chrome 56功能-www.chromestatus.com/features#milestone%3D56


4
刚刚有一些用户报告了此错误。另外,其他一些用户没有升级版本,因此他们可以毫无问题地提交表单。使错误更加不一致。感谢您的回答!
Ironicnet'2

像原始问题一样,与jQuery结合使用时,建议的解决方案对我不起作用。相反,它起作用了: $(document.body).append(form);
克里斯(Chris)

1
@Chris我刚刚编辑了接受的答案,因为form变量是一个jQuery对象,而不是实际的DOM form元素。在使用时form[0],将产生错误“无法在'Node'上执行'appendChild':参数1不是'Node'类型”。在Chrome中。因此,只需更改为document.body.appendChild(form[0])
ryanm

@ryanm,我只是一位编辑,因为我贡献了以下内容$(document.body).append(form);。欢迎您编辑解决方案,或者询问@KyungHun Jeon是否要采用您的解决方案代替他,将您的解决方案添加到接受的答案中。
克里斯(Chris

@克里斯谢谢!我认为由于问题是在jQuery中,所以答案也应该是(可能造成混淆),但是我的编辑似乎被拒绝了。只是给其他路人一个便条,便是document.body.appendChild(form[0])(稍快)或$(document.body).append(form)
ryanm

50

如果您在尝试按Enter提交表单时在React JS中看到此错误,请确保表单中所有未提交表单的按钮都带有一个type="button"

如果你只有一个buttontype="submit"按Enter键将提交表单预期。

参考
https : //dzello.com/blog/2017/02/19/demystifying-enter-key-submission-for-react-forms/ https://github.com/facebook/react/issues/2093


6
这也是在React中需要注意的事情,<form>仍然需要在单击后在DOM中进行渲染。即,这将失败`{this.state.submitting?<div>正在提交表单</ div>:<form onSubmit = {()=> this.setState({submitting:true})...> <button ...> </ form>}`提交表单,state.submitting设置表单,然后呈现“ submitting ...”消息(而不是表单),然后发生此错误。将form标签移到条件标签之外,以确保在需要时始终将其放置在那里。
Mike Ruhlin

很高兴知道。我猜您不必将整个form元素更改为div。我相信,如果您只是更改form而不是替换元素的内容,它将按预期工作。
vaskort

因此,就像Max Williams所说的,这是一个竞争条件-浏览器正在检查表单是否存在,但是表单已经消失了。
钢琴詹姆斯

preventDefault()会导致Chrome
发出

第一个链接已断开:web.archive.org/web/20170410070341/http
cmp


11

您必须确保该表单在文档中。您可以将表单附加到正文。


7
我知道了,结果发现在远程表单提交按钮上添加了onclick,它删除了表单的包含元素。因此,在提交的表单和删除的表单之间基本上存在竞争条件。
Max Williams

4
感谢@Max Williams,您的留言使我比已接受的答案重回正轨。
JirkaV


8

我看到您正在使用jQuery进行表单初始化。

当我尝试@KyungHun Jeon的答案时,使用jQuery也不适合我。

因此,我尝试使用jQuery方式将表单追加到正文中:

$(document.body).append(form);

而且有效!


6

如果您在React中看到这一点,需要注意的是,<form>仍然需要在DOM提交时在DOM中进行渲染。即,这将失败

{ this.state.submitting ? 
     <div>Form is being submitted</div> :
     <form onSubmit={()=>this.setState({submitting: true}) ...>
         <button ...>
     </form>
}

因此,当提交表单,state.submitting设置表单并呈现“ submitting ...”消息而不是表单时,就会发生此错误。

将表单标签移至条件之外,以确保在需要时始终存在该标签,即

<form onSubmit={...} ...>
  { this.state.submitting ? 
     <div>Form is being submitted</div> :
     <button ...>
  }
</form>

比赛条件!
钢琴詹姆斯

2

在我们的一项实现中,我遇到了同样的问题。

我们正在使用jquery.forms.js。这是一个表单插件,可在此处获得。http://malsup.com/jquery/form/

我们使用上面提供的相同答案并粘贴

$(document.body).append(form);

并且成功了。谢谢。


1

根据KyungHun Jeon的回答,但是appendChild需要一个dom节点,因此请向jquery对象添加索引以返回该节点: document.body.appendChild(form[0])


2
你的意思是document.body.appendChild(form[0])
efeder

1

添加后代,因为这与Chrome无关,但这是搜索此表单提交错误时在Google上显示的第一个线程。

在我们的案例中,我们附加了一个函数,用于在提交时用“加载”动画替换当前的div html-因为它发生在提交表单之前,所以不再有任何表单或数据可以提交。

回想起来非常明显的错误,但是万一有人落在这里,将来可能会节省一些时间。


1

我在react.js中收到此错误。如果您要在表单中使用某个按钮,但不想提交该表单,则必须将其设为type =“ button”。否则,它将尝试提交表单。我相信vaskort会提供一些文档供您参考。


这是一个警告:表单提交已取消,因为该表单未连接。很抱歉忘记添加。
艾赛尔·拉森

1
我可以确认这一点。Form submission canceled because the form is not connected每当我按下表单的“取消”按钮时,我都会在React中收到相同的警告。添加type="button"到“取消”按钮后,我不再收到警告。谢谢!


0

您也可以通过在jquery-xxxjs中应用单个补丁来解决此问题,只需在“ try {rp;} catch(m){}”行1833行之后添加以下代码:

if (r instanceof HTMLFormElement &&! r.parentNode) { r.style.display = "none"; document.body.append (r); r [p] (); }

这会验证表单是否不是正文的一部分并将其添加。


-1

我看到此消息是使用angular的,所以我只取出了method =“ post”和action =“”,警告就消失了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.