拥有一个具有多个同名“隐藏”控制元素的 HTML 表单是否合法?我希望在服务器上获得所有这些元素的值。如果合法,各大浏览器是否正确实现了该行为?
8 回答
浏览器没问题。但是,应用程序库如何解析它可能会有所不同。
程序应该将同名的项目组合在一起。虽然 HTML 规范没有明确说明这一点,但在有关 checkboxes 的文档中隐含地说明了这一点:
一个表单中的多个复选框可以共享相同的控件名称。因此,例如,复选框允许用户为同一属性选择多个值。
不同的服务器端技术会有所不同。使用 PHP,您可以对名称使用数组样式的语法来强制在服务器端创建集合。如果发布到服务器,$_POST['colors']
将是一个包含两个值的数组,#003366
并且#00FFFF
:
<input type="hidden" name="colors[]" value="#003366" />
<input type="hidden" name="colors[]" value="#00FFFF" />
一般来说,您需要使用不带方括号的标准名称。大多数服务器端技术将能够解析结果数据,并提供某种类型的集合。Node.js 通过以下方式提供有用的功能querystring.parse
:
const querystring = require('querystring')
querystring.parse('foo=bar&abc=xyz&abc=123') // { foo: 'bar', abc: ['xyz', '123'] }
如果你有这样的事情:
<input type="hidden" name="x" value="1" />
<input type="hidden" name="x" value="2" />
<input type="hidden" name="x" value="3" />
您的查询字符串将看起来像x=1&x=2&x=3
... 根据您用于解析查询字符串的服务器软件,这可能无法正常工作。
是的,大多数应用程序服务器会收集匹配的元素并用逗号将它们连接起来,这样的形式如下:
<html>
<form method="get" action="http://myhost.com/myscript/test.asp">
<input type="hidden" name="myHidden" value="1">
<input type="hidden" name="myHidden" value="2">
<input type="hidden" name="myHidden" value="3">
<input type="submit" value="Submit">
</form>
</html>
... 将解析为一个 URL(在 GET 情况下 - POST 会以相同的方式工作),如下所示:
http://myhost.com/myscript.asp?myHidden=1&myHidden=2&myHidden=3
...并且会以这样的代码向您公开:(例如,遵循类似 Response.Write(Request.QueryString("myHidden")):
1、2、3
因此,要获取这些值,您只需拆分字符串并将它们作为数组(或您选择的任何可比较的语言)访问。
(应该澄清:在 PHP 中,它略有不同(正如 Johnathan 指出的那样,括号表示法将项目作为数组公开给 PHP 代码),但 ASP、ASP.NET 和 ColdFusion 都将值公开为逗号分隔的列表. 所以是的,重复的命名是完全有效的。)
HTML5
非规范部分4.10.1.3 配置表单以与服务器通信明确表示它是有效的:
多个控件可以具有相同的名称;例如,这里我们为所有复选框赋予相同的名称,并且服务器通过查看使用该名称提交的值来区分哪个复选框被选中 - 就像单选按钮一样,它们也被赋予具有 value 属性的唯一值。
规范的版本很简单,它在任何地方都没有被禁止,并且表单提交算法准确地说明了应该生成什么请求:
- 没有违反约束:https ://www.w3.org/TR/html5/forms.html#constraints
- 多个名称一个接一个地添加到“表单数据集”中:https ://www.w3.org/TR/html5/forms.html#constructing-form-data-set
- 像循环“表单数据集”这样的编码
application/x-www-form-urlencoded
并吐出多个key=val
https://www.w3.org/TR/html5/forms.html#url-encoded-form-data
特别是对于 PHP,我在隐藏输入中使用数组名称进行了一些测试,并在这里分享我的结果:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Post Hidden 2D Arrays</title>
</head>
<body>
<form name="formtest" method="POST" target="_self">
<input type="hidden" name="elem['name'][]" value="first">
<input type="hidden" name="elem['name'][]" value="second">
<input type="hidden" name="elem['name'][]" value="third">
<input type="hidden" name="elem['name'][]" value="fourth">
<input type="hidden" name="elem['type'][]" value="normal">
<input type="hidden" name="elem['type'][]" value="classic">
<input type="hidden" name="elem['type'][]" value="regular">
<input type="hidden" name="elem['type'][]" value="basic">
<input type="hidden" name="elem['size'][]" value="4">
<input type="hidden" name="elem['size'][]" value="7">
<input type="hidden" name="elem['size'][]" value="3">
<input type="hidden" name="elem['size'][]" value="6">
<input type="hidden" name="elem['form'][]" value="triangle">
<input type="hidden" name="elem['form'][]" value="square">
<input type="hidden" name="elem['form'][]" value="hexagon">
<input type="hidden" name="elem['form'][]" value="circle">
<input type="submit" name="sendtest" value="Test">
</form>
<xmp>
<?php
print_r($_POST);
?>
</xmp>
</body>
</html>
提交表单会生成下一个结果:
Array
(
[elem] => Array
(
['name'] => Array
(
[0] => first
[1] => second
[2] => third
[3] => fourth
)
['type'] => Array
(
[0] => normal
[1] => classic
[2] => regular
[3] => basic
)
['size'] => Array
(
[0] => 4
[1] => 7
[2] => 3
[3] => 6
)
['temp'] => Array
(
[0] => triangle
[1] => square
[2] => hexagon
[3] => circle
)
)
[sendtest] => Test
)
查看此结果后,我进行了更多测试,以寻找更好的数组值排列并以此结束(我将仅显示新的隐藏输入):
<input type="hidden" name="elem[0]['name']" value="first">
<input type="hidden" name="elem[1]['name']" value="second">
<input type="hidden" name="elem[2]['name']" value="third">
<input type="hidden" name="elem[3]['name']" value="fourth">
<input type="hidden" name="elem[0]['type']" value="normal">
<input type="hidden" name="elem[1]['type']" value="classic">
<input type="hidden" name="elem[2]['type']" value="regular">
<input type="hidden" name="elem[3]['type']" value="basic">
<input type="hidden" name="elem[0]['size']" value="4">
<input type="hidden" name="elem[1]['size']" value="7">
<input type="hidden" name="elem[2]['size']" value="3">
<input type="hidden" name="elem[3]['size']" value="6">
<input type="hidden" name="elem[0]['temp']" value="triangle">
<input type="hidden" name="elem[1]['temp']" value="square">
<input type="hidden" name="elem[2]['temp']" value="hexagon">
<input type="hidden" name="elem[3]['temp']" value="circle">
提交表单后得到这个结果:
Array
(
[elem] => Array
(
[0] => Array
(
['name'] => first
['type'] => normal
['size'] => 4
['temp'] => triangle
)
[1] => Array
(
['name'] => second
['type'] => classic
['size'] => 7
['temp'] => square
)
[2] => Array
(
['name'] => third
['type'] => regular
['size'] => 3
['temp'] => hexagon
)
[3] => Array
(
['name'] => fourth
['type'] => basic
['size'] => 6
['temp'] => circle
)
)
[sendtest] => Test
)
我希望这对一些人有所帮助。
我相信这是合法的,至少在单选按钮和复选框的情况下是这样。当我必须在 XSLT 中动态添加文本框输入时,我给它们都赋予了相同的名称;在 ASP.NET 中,Request.Form["whatever_name"] 是所有这些值以逗号分隔的字符串。
我刚刚尝试对几个 SELECT 输入使用相同的控件名称counties[],以便英格兰、苏格兰、威尔士和爱尔兰的县都作为相同参数的值传递。PHP 处理得很好,但 HTML 验证器会发出警告。我不知道是否所有浏览器都会以同样的方式处理这个问题。