表单元素是 HTML 文档中最常用的元素,根据 W3C HTML4.01 规范中的描述,表单(FORM)元素是文档(Document)的一部分,它可以包含常规文本内容、其他 HTML 标记、控件及 LABEL 元素。用户通常在对表单内的空间进行填写或修改之后提交给某一个代理(agent,如 Web 服务器、Mail 服务器)进行处理。
表单的提交过程主要分为以下四步:
successful controls 是指可以有效的提交的控件。每一个 successful controls 均具备由其 name 属性(control name)及当前 value 属性(current value)所组成的“name/value”键值对,这些 successful controls 的键值对组成了 form data set。而 W3C 规定,定义在 FORM 元素内的 successful controls 必须拥有 name 属性。
规范还做出了如下规定:
若一个控件在表单提交时没有当前 value 属性,不要求用户端一定将其视为 successful controls。
同时规范中特别提到重置按钮(reset button)不应该被认作 successful controls。而隐藏域(hidden)及被隐藏的符合 successful controls 条件的控件虽然不会被渲染,但仍然应被认为是successful controls。
关于 表单 的详细信息,请参考 HTML4.01 规范 17 Forms 中的内容。
IE Firefox Opera 在自定义提交方式下不会提交普通按钮及提交按钮的键值对信息;而 Chrome Safari 会将这些信息也提交给服务器端。
通常情况下,不同浏览器在表单提交时 form data set 中键值对的差异不会造成太大问题,但若服务器端程序对浏览器端提交来的 form data set 进行较严格的判断时,可能会造成在某些浏览器中表单提交异常。如:
一般在登录表单中,我们都会使用自定义 onsubmit 事件的方式,此方式通过 JavaScript 为用户输入的表单信息作初步的验证,且提交方式多数为 POST 方式,当提交按钮有 name 属性时,IE、Firefox、Opera 均不会将提交按钮自身的“name/value”添加到 form data set 中,Chrome 和 Safari 则会将提交按钮自身的信息加入 form data set。这时候服务器端收到的 request header 就会不同,若目的地址的服务端程序对提交来的 form data set 进行了严格的判断,这时 Chrome 和 Safari 提交的信息中比其他浏览器多出的提交按钮的键值对就有可能造成登录失败。
Chrome Safari |
---|
在本地创建一个 Web 服务器,编写四个静态页面:
<form action="submit.php" method="METHOD" onsubmit="ONSUBMIT" target="iframe1" enctype="multipart/form-data"> <iframe name="iframe1"></iframe> <input type="submit" name="I0" value="提交" /> <input type="text" name="I1" value="input_text" /> <input type="password" name="I2" value="input_password" /> <input type="checkbox" name="I3" checked /> <input type="radio" name="I4" checked /> <input type="hidden" name="I5" value="input_hidden" /> <input type="image" name="I6" src="google.gif" value="input_image" /> <input type="button" name="I7" value="input_button" /> <input type="file" name="I8" value="input_file" /> <input type="reset" name="I9" value="input_reset" /> <input type="text" name="I10" /> <input type="file" name="I11" /> <input type="radio" name="I12" /> <input type="checkbox" name="I13" /> <select name="S1"><option>select</option></select> <select name="S2"></select> <button name="B1" type="button">button</button> <textarea name="T1">textarea</textarea> </form>
静态页面实际为四组 FORM 元素,区别为 method 属性及 onsubmit 事件:
onsubmit="" | onsubmit="this.submit(); return false;" | |
---|---|---|
method="get" | 第一组“form1.html” | 第二组“form2.html” |
method="post" | 第三组“form3.html” | 第四组“form4.html” |
各组中均是由一个 FORM 元素,将其内部一系列表单控件元素的 form data set 提交到“submit.php”,并在 IFRAME 元素中显示提交后的结果页面。
服务器端动态页面“submit.php”代码如下:
<?php $gp = $_REQUEST; foreach ($gp as $k=>$v) { echo $k . "/" . $v . "<br />"; } $fp = $_FILES; foreach ($fp as $kf=>$kv) { echo $kf . "/" . $kv["name"] . "<br />"; } ?>
“submit.php”的作用是将客户端表单提交来的 form data set 遍历打印出来。
这段代码在不同的浏览器环境中的表现如下(绿色背景文字代表服务器端返回的有效数据,红色背景文字代表服务器端未返回的数据):
第一组、第三组
点击“I0”提交 |
IE6/7, IE8(Q) | IE8(S), Firefox, Opera | Chrome, Safari |
---|---|---|---|
提交按钮 | 提交 | 提交 | 提交 |
带内容的文本框 | 提交 | 提交 | 提交 |
带内容的密码框 | 提交 | 提交 | 提交 |
选中的复选框 | 提交 | 提交 | 提交 |
选中的单选框 | 提交 | 提交 | 提交 |
带内容的隐藏域 | 提交 | 提交 | 提交 |
提交图片 | 不提交 | 不提交 | 不提交 |
INPUT普通按钮 | 不提交 | 不提交 | 不提交 |
已选文件的文件组件 | 提交 | 提交 | 提交 |
重置按钮 | 不提交 | 不提交 | 不提交 |
空的文本框 | 提交 | 提交 | 提交 |
未选文件的文件组件 | 提交 | 提交 | 提交 |
未选中的复选框 | 不提交 | 不提交 | 不提交 |
未选中的单选框 | 不提交 | 不提交 | 不提交 |
有选中的下拉框 | 提交 | 提交 | 提交 |
未选中的下拉框 | 不提交 | 不提交 | 不提交 |
BUTTON普通按钮 | 提交1 | 不提交 | 不提交 |
多行文本框 | 提交 | 提交 | 提交 |
第一组、第三组
点击“I6”提交 |
IE6/7, IE8(Q) | IE8(S), Opera | Firefox, Chrome, Safari |
---|---|---|---|
提交按钮 | 不提交 | 不提交 | 不提交 |
带内容的文本框 | 提交 | 提交 | 提交 |
带内容的密码框 | 提交 | 提交 | 提交 |
选中的复选框 | 提交 | 提交 | 提交 |
选中的单选框 | 提交 | 提交 | 提交 |
带内容的隐藏域 | 提交 | 提交 | 提交 |
提交图片 | 提交2 | 提交2 | 提交 |
INPUT普通按钮 | 不提交 | 不提交 | 不提交 |
已选文件的文件组件 | 提交 | 提交 | 提交 |
重置按钮 | 不提交 | 不提交 | 不提交 |
空的文本框 | 提交 | 提交 | 提交 |
未选文件的文件组件 | 提交 | 提交 | 提交 |
未选中的复选框 | 不提交 | 不提交 | 不提交 |
未选中的单选框 | 不提交 | 不提交 | 不提交 |
有选中的下拉框 | 提交 | 提交 | 提交 |
未选中的下拉框 | 不提交 | 不提交 | 不提交 |
BUTTON普通按钮 | 提交 | 不提交 | 不提交 |
多行文本框 | 提交 | 提交 | 提交 |
第二组、第四组
点击“I0”提交 |
IE6/7, IE8(Q) | IE8(S), Firefox, Opera | Chrome, Safari |
---|---|---|---|
提交按钮3 | 不提交 | 不提交 | 提交 |
带内容的文本框 | 提交 | 提交 | 提交 |
带内容的密码框 | 提交 | 提交 | 提交 |
选中的复选框 | 提交 | 提交 | 提交 |
选中的单选框 | 提交 | 提交 | 提交 |
带内容的隐藏域 | 提交 | 提交 | 提交 |
提交图片 | 不提交 | 不提交 | 不提交 |
INPUT普通按钮 | 不提交 | 不提交 | 不提交 |
已选文件的文件组件 | 提交 | 提交 | 提交 |
重置按钮 | 不提交 | 不提交 | 不提交 |
空的文本框 | 提交 | 提交 | 提交 |
未选文件的文件组件 | 提交 | 提交 | 提交 |
未选中的复选框 | 不提交 | 不提交 | 不提交 |
未选中的单选框 | 不提交 | 不提交 | 不提交 |
有选中的下拉框 | 提交 | 提交 | 提交 |
未选中的下拉框 | 不提交 | 不提交 | 不提交 |
BUTTON普通按钮 | 提交 | 不提交 | 不提交 |
多行文本框 | 提交 | 提交 | 提交 |
第二组、第四组
点击“I6”提交 |
IE6/7, IE8(Q) | IE8(S), Firefox, Opera | Chrome, Safari |
---|---|---|---|
提交按钮 | 不提交 | 不提交 | 不提交 |
带内容的文本框 | 提交 | 提交 | 提交 |
带内容的密码框 | 提交 | 提交 | 提交 |
选中的复选框 | 提交 | 提交 | 提交 |
选中的单选框 | 提交 | 提交 | 提交 |
带内容的隐藏域 | 提交 | 提交 | 提交 |
提交图片3 | 不提交 | 不提交 | 提交 |
INPUT普通按钮 | 不提交 | 不提交 | 不提交 |
已选文件的文件组件 | 提交 | 提交 | 提交 |
重置按钮 | 不提交 | 不提交 | 不提交 |
空的文本框 | 提交 | 提交 | 提交 |
未选文件的文件组件 | 提交 | 提交 | 提交 |
未选中的复选框 | 不提交 | 不提交 | 不提交 |
未选中的单选框 | 不提交 | 不提交 | 不提交 |
有选中的下拉框 | 提交 | 提交 | 提交 |
未选中的下拉框 | 不提交 | 不提交 | 不提交 |
BUTTON普通按钮 | 提交 | 不提交 | 不提交 |
多行文本框 | 提交 | 提交 | 提交 |
【注】
1. 在 IE6、IE7、IE8(Q) 下,始终认为 BUTTON 元素的普通按钮是successful
control,其他浏览器始终认为 BUTTON 元素的普通按钮不是successful control;。
2. 在 IE、Opera 下,始终不提交 INPUT 图片的 value 属性;
3. 在 IE、Firefox、Opera
下,使用“form.submit()”方法自定义提交时(第二组、第四组),浏览器认为提交按钮或图片不是successful control,在 Chrome、Safari 下,始终认为提交按钮或图片是successful
control,且会同时将其 value 属性的值也放入 form data set。
通常情况下,服务器端不需要按钮的 key/value 信息,建议删除按钮的 name 属性,不使其成为 successful control。
操作系统版本: | Windows 7 Ultimate build 7600 |
---|---|
浏览器版本: |
IE6
IE7 IE8 Firefox 3.6 Chrome 5.0.342.2 dev Safari 4.0.4 Opera 10.50 |
测试页面: |
form1.html
form2.html form3.html form4.html |
本文更新时间: | 2010-08-02 |
form submit 表单 key value 键值 提交 按钮 input name