【问题标题】:HTML form with multiple hidden control elements of the same name具有多个同名隐藏控件元素的 HTML 表单
【发布时间】:2010-10-01 21:52:24
【问题描述】:

拥有多个同名“隐藏”控制元素的 HTML 表单是否合法?我希望在服务器上获得所有这些元素的值。如果合法,各大浏览器是否正确实现了该行为?

【问题讨论】:

    标签: forms hidden-field


    【解决方案1】:

    浏览器没问题。但是,应用程序库解析它的方式可能会有所不同。

    程序应该将同名的项目组合在一起。虽然 HTML 规范没有明确说明这一点,但在 documentation on checkboxes 中隐含说明:

    一个表单中的多个复选框可以共享 相同的控件名称。因此,对于 例如,复选框允许用户 选择多个相同的值 属性。

    【讨论】:

    • 旁注(6 年后):ASP.NET 在其复选框控件旁边使用隐藏的表单字段,以便它知道复选框控件存在。这是 HTML 不发送未选中复选框的名称的解决方法。
    【解决方案2】:

    不同的服务器端技术会有所不同。使用 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'] }
    

    【讨论】:

    • 我以前从未见过这种数组语法。
    • 如果您将相关详细信息的集合传递到服务器,此方法非常有用,因为它允许它们作为一个组旅行,而不是许多独立的值。
    • 方括号里的东西是 PHP 的发明,不是任何一种 web 标准。其他语言和表单阅读库有不同的机制来访问同名的多个提交,不一定需要像这样更改名称。
    • 在 ASP.net 中,您可以通过调用 Request.Form.GetValues 来获取发布的值数组。例如:string[] postedValues = Request.Form.GetValues("name_of_the_elements"); 或 Request.QueryString.GetValues("name_of_the_elements")。
    • 7 年了,这还能用吗?这种数组技术是否适用于其他服务器端技术,例如 node.js?
    【解决方案3】:

    如果你有这样的事情:

    <input type="hidden" name="x" value="1" />
    <input type="hidden" name="x" value="2" />
    <input type="hidden" name="x" value="3" />
    

    您的查询字符串将看起来像 x=1&amp;x=2&amp;x=3... 根据您用于解析查询字符串的服务器软件,这可能无法正常工作。

    【讨论】:

    • 你知道是否指定了排序吗?我只发现它将是一个序列,但不是按照声明的方式排序的。那么你会不会得到x=2&amp;x=3&amp;x=1?
    • 如果有人想知道,PHP 将始终在此类示例中使用最后一个输入元素中的值
    【解决方案4】:

    是的,大多数应用程序服务器会收集匹配的元素并用逗号将它们连接起来,这样的形式如下:

    <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 都将值公开为逗号- 分隔列表。所以是的,重复的命名是完全有效的。)

    【讨论】:

    • 抱歉,我应该更具体一点:“除了 PHP 之外的所有内容。” ;) ASP、ASP.NET、CF 都是这样操作的。正如 Johnathan 在他的回答中提到的那样,除非指定了括号表示法,否则 PHP 对列表中的最后一项具有特权。关键是 HTML 语法是有效的。
    • 添加了 PHP 注释以进行澄清。
    • 所以除了 PHP、Perl CGI.pm、Python cgi.py、htmlform、django 等、Ruby on Rails、Java Servlet 之外的一切......
    • 我认为 CGI.pm 是这样工作的——当然它也适用于复选框。我目前对 CGI::Application 的实验(首先让我想到了这个问题)现在似乎同意了。
    • 如果您使用的是 asp.net,并且想要获取不带逗号的单个值,您可以使用 request.QueryString.GetValues("myHidden") 返回一个数组。 msdn.microsoft.com/en-us/library/4ba5htte%28v=vs.90%29.aspx
    【解决方案5】:

    HTML5

    非规范部分4.10.1.3 Configuring a form to communicate with a server 明确表示它是有效的:

    多个控件可以同名;例如,这里我们为所有复选框赋予相同的名称,服务器通过查看使用该名称提交的值来区分哪个复选框被选中 - 就像单选按钮一样,它们也被赋予具有 value 属性的唯一值。

    这个的规范版本很简单,它在任何地方都没有被禁止,并且表单提交算法准确地说明了应该生成什么请求:

    【讨论】:

      【解决方案6】:

      特别是对于 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
      )
      

      我希望这对一些人有所帮助。

      【讨论】:

        【解决方案7】:

        我相信这是合法的,至少在单选按钮和复选框的情况下是这样。当我必须在 XSLT 中动态添加文本框输入时,我给它们都赋予相同的名称;在 ASP.NET 中,Request.Form["whatever_name"] 是所有这些值以逗号分隔的字符串。

        【讨论】:

          【解决方案8】:

          我刚刚尝试对几个 SELECT 输入使用相同的控件名称,counties[],以便英格兰、苏格兰、威尔士和爱尔兰的每个县都作为相同参数的值传递。 PHP 处理得很好,但 HTML 验证器会发出警告。我不知道是否所有浏览器都会以同样的方式处理这个问题。

          【讨论】:

            猜你喜欢
            • 2016-12-06
            • 1970-01-01
            • 1970-01-01
            • 2017-07-11
            • 2023-03-08
            • 1970-01-01
            • 1970-01-01
            • 2011-12-04
            • 1970-01-01
            相关资源
            最近更新 更多