为什么只有一个输入字段的表单按下回车键后会提交?

86
为什么一个只有一个<input>字段的<form>在用户输入值并按下Enter时会重新加载表单,而如果<form>中有2个或更多字段,则不会重新加载? 我写了一个简单页面来测试这个奇怪的问题。如果您在第二个表单中输入一个值并按Enter键,则会看到它重新加载页面,将输入的值作为GET调用。为什么?我该如何避免这种情况?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>testFormEnter</title>
</head>
<body>
<form>
  <input type="text" name="partid2" id="partid2" />
  <input type="text" name="partdesc" id="partdesc"  />
</form>
  <p>2 field form works fine</p>
<form>
<input type="text" name="partid" id="partid"  />
</form>
<p>One field form reloads page when you press the Enter key why</p>
</body>
</html>
13个回答

62

这是一个不太为人知的“怪癖”,已经存在一段时间了。我知道有些人以各种方式解决了它。

在我看来,最简单的绕过方法是简单地拥有第二个输入,该输入不向用户显示。尽管后端不太友好,但确实可以解决问题。

需要注意的是,我听说这个问题最常见于IE,而不是FireFox或其他浏览器。虽然它似乎也会影响它们。


4
谢谢,我希望这些内容能有所记录。我浪费了数小时来调试一个大页面,认为问题与我的 Ajax 有关,但事实上是由于这个“怪异”的问题。只有在我逐行删除代码后才发现这一点。太浪费时间了! - sdfor
2
你是正确的,这很容易通过添加一个隐藏字段来解决。顺便提一下,这会影响到 Firefox 3.5.2。也许它被认为是一个特性。 - sdfor
啊,是的,我感受到了你的痛苦...这就是我5-6年前发现它的方式... - Mitchel Sellers
2
我还发现隐藏字段并不总是有效。在一个页面上它有效,在另一个页面上却无效 - 这也很奇怪。但使用JavaScript隐藏该字段就解决了问题。你需要写一篇文章《你不知道的会浪费你时间的事情》- 再次感谢。 - sdfor
3
我正在使用Chrome进行调试,但隐藏字段似乎不起作用。 - Chris
添加一种样式,将显示设置为“none”,而非将类型设置为“hidden”。 - Tychio

50

这是IE6/7/8中已知的一个bug。看起来你不会得到修复。

最好的解决方法是添加另一个隐藏字段(如果你的工程良心允许)。当表单中存在两个输入类型字段时,IE将不再自动提交表单。

更新

如果您想知道为什么会出现这种情况,那么这个宝石直接来自HTML 2.0规范(第8.2节)

 

当表单中只有一个单行文本输入字段时,用户代理应该接受该字段中的Enter作为提交表单的请求。


1
这也发生在Firefox 3.5中。 - cssmaniac
1
在Chrome中调试了几个小时,感谢指出它来自规范。 - JM Yang
当你一个自以为是的开发者因为没有仔细阅读文档被w3org“按设计要求,看一看文档吧”时,你会感到无比尴尬。 - Nathan
如果这是一个 bug,那只是因为 IE 坚持实现远超过保质期的 HTML 2.0。你发现的那个部分在你回答时已经非常过时了:HTML 2.0 发布于1995年,之后在1997年被 HTML 3.2 取代。这个标准已经不再规定浏览器如何处理表单提交。HTML 4.0(1999年)仅仅讲述了激活提交按钮的例子来说明表单提交。 - Martijn Pieters
2
最终,HTML 5于2012年发布(即在您的回答之后3年),增加了隐式表单提交的概念,将浏览器一直在执行的操作进行了编码:当用户在单行文本字段中按下回车键时,提交表单。 - Martijn Pieters
添加隐藏字段无法生效。浏览器(chrome)仍然会提交表单。 - LP13

9
不,表单默认行为是在按下回车键时提交最后一个输入框中的内容。如果您不想提交任何内容,可以添加以下代码:
<form onsubmit="return false;">

在您的输入中。
<input ... onkeypress="return event.keyCode != 13;">

当然,还有更美观的解决方案,但这些更简单,没有任何库或框架。

我最近在我的网站上遇到了这个问题。我觉得最新版本的 Chrome 现在实施了 W# SEC8.2,导致我正在开发的一些网站功能出现了故障。 - David

7
按下回车键的行为取决于(a)有多少个字段和(b)有多少个提交按钮。它可能什么也不做,可能会提交没有成功提交按钮的表单,或者可能会假装已点击第一个提交按钮(甚至为其生成onclick!),并使用该按钮的值进行提交。
例如,如果向两个字段的表单中添加,您将注意到它同样会提交。
这是一个古老的浏览器怪癖,至少追溯到早期Netscape(可能更早),现在不太可能更改。

<form>

如果没有'action'无效。如果您不打算提交任何地方,并且不需要收音机按钮名称分组,则可以完全省略表单元素。

谢谢,好的回答。虽然我需要表单将字段序列化为Ajax。我可以手动编码,但对于许多表单来说,这将是一种痛苦。 - sdfor

7
这是我用来解决问题的代码:
<form>
<input type="text" name="partid" id="partid"  />
<input type="text" name="StackOverflow1370021" value="Fix IE bug" style="{display:none}" />
</form>

3

它并不是重新加载页面,而是提交表单。

但是,在这个例子中,因为表单上没有action属性,它会提交到自身,从而给人以重新加载页面的印象。

此外,我无法复现您所描述的行为。如果我在表单中的任何文本输入框中按Enter键,它都会提交表单,无论输入框位于表单中的哪个位置或者有多少个输入框。

您可能需要在不同的浏览器中尝试一下。


你说得对,我使用的词不正确。实际上是提交表单,由于我没有指定动作,所以默认为自身。我复制了完全相同的HTML代码,在IE8和Firefox 3.5.2中运行。在第一个表单中的前两个字段中按下Enter键不会提交表单,而在第三个字段中按下Enter键会提交表单。 - sdfor

3
如Vineet所说,这源于HTML 2.0规范:
以下是如何在不弄乱URL的情况下防止这种情况发生的方法:
<form>
    <input type="text" name="partid" id="partid"  />
    <input type="text" style="display: none;" />
</form>

1
我针对所有经过测试的浏览器(IE、FF、Chrome、Safari、Opera)找到的解决方案是,表单中的第一个输入元素type=submit必须可见,并且必须是表单中的第一个元素。我可以使用CSS定位将提交按钮移动到页面底部,且不会影响结果!
<form id="form" action="/">
<input type="submit" value="ensures-the-enter-key-submits-the-form"
                      style="width:1px;height:1px;position:fixed;bottom:1px;"/>
<div id="header" class="header"></div>
<div id="feedbackMessages" class="feedbackPanel"></div>
     ...... lots of other input tags, etc...
</form>

1
感谢所有回答的人。一个只有一个字段的表单和一个有多个字段的表单是不同的,这是一个启示。
另一种处理自动提交的方法是编写一个返回 false 的提交函数。
在我的情况下,我有一个带有 onclick 事件的按钮,所以我将带有添加了 return 关键字的函数调用移动到 onsubmit 事件中。如果被调用的函数返回 false,则提交不会发生。
<form onsubmit="return ajaxMagic()">
<input type="text" name="partid" id="partid"  />
<input type="submit" value="Find Part" />
</form

function ajaxMagic() {
  ...
  return (false);
}

0

是的,只有一个inputText字段的表单在HTML 4中的工作方式不同。
对于我来说,onSubmit返回false无效,但下面的修复程序可以正常工作。

<!--Fix  IE6/7/8 and  HTML 4 bug -->
    <input style="display:none;" type="text" name="StackOverflow1370021" value="Fix IE bug" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接