web-dev-qa-db-fra.com

Formulaire HTML avec plusieurs éléments de contrôle cachés du même nom

Est-il légal d'avoir un formulaire HTML avec plus d'un élément de contrôle "caché" du même nom? Je m'attends à obtenir les valeurs de tous ces éléments sur le serveur. S'il est légal, les principaux navigateurs implémentent-ils le comportement correctement?

47
Brian

Les navigateurs sont d'accord avec ça. Cependant, la façon dont la bibliothèque d’application l’analyse peut varier.

Les programmes sont supposés pour regrouper des éléments de même nom. Bien que la spécification HTML ne le dise pas explicitement, c'est indiqué implicitement dans la documentation sur les cases à cocher :

Plusieurs cases d'un formulaire peuvent partager le même nom de contrôle. Ainsi, pour Par exemple, les cases à cocher permettent aux utilisateurs de sélectionnez plusieurs valeurs pour le même propriété.

36
Powerlord

Différentes technologies côté serveur varieront. Avec PHP, vous pouvez utiliser une syntaxe de type tableau pour le nom afin de forcer la création d'une collection sur le serveur. Si posté sur le serveur, $_POST['colors'] sera un tableau avec deux valeurs, #003366 et #00FFFF:

<input type="hidden" name="colors[]" value="#003366" />
<input type="hidden" name="colors[]" value="#00FFFF" />

En règle générale, vous souhaiterez utiliser un nom name standard sans crochets. La plupart des technologies côté serveur pourront analyser les données résultantes et fournir une collection d'un certain type. Node.js fournit des fonctionnalités utiles via querystring.parse :

const querystring = require('querystring')

querystring.parse('foo=bar&abc=xyz&abc=123') // { foo: 'bar', abc: ['xyz', '123'] }
26
Sampson

Si vous avez quelque chose comme ça:

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

Votre chaîne de requête va ressembler à x=1&x=2&x=3... Selon le logiciel serveur que vous utilisez pour analyser la chaîne de requête, il se peut que cela ne fonctionne pas bien.

18
DavGarcia

Oui, et la plupart des serveurs d'applications collecteront les éléments correspondants et les concaténeront avec des virgules, de sorte qu'un formulaire comme celui-ci:

<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>

... serait résolu en une URL (dans le cas GET - POST fonctionnerait de la même manière, cependant) comme ceci:

http://myhost.com/myscript.asp?myHidden=1&myHidden=2&myHidden=3

... et vous seraient exposés dans un code comme celui-ci: (par exemple, en suivant quelque chose comme Response.Write (Request.QueryString ("myHidden"))):

1, 2, 3

Donc, pour saisir les valeurs, vous devez simplement scinder la chaîne et y accéder sous forme de tableau (ou de tout ce qui est comparable dans la langue de votre choix). 

(Doit être clarifié: en PHP, c'est légèrement différent (comme le souligne Johnathan, la notation entre crochets expose les éléments sous forme de tableau à votre code PHP), mais ASP, ASP.NET et CF exposent tous les valeurs comme suit: une liste séparée par des virgules, donc oui, le nom du doublon est tout à fait valide.)

5
Christian Nunciato

HTML5

La section non normative 4.10.1.3 Configurer un formulaire pour communiquer avec un serveur indique explicitement qu'il est valide:

Plusieurs contrôles peuvent avoir le même nom. Par exemple, ici, nous donnons le même nom à toutes les cases à cocher, et le serveur distingue les cases cochées en vérifiant les valeurs soumises avec ce nom - comme les boutons radio, elles reçoivent également des valeurs uniques avec l'attribut value.

La version normative de ceci est simplement qu'il n'est interdit nulle part, et l'algorithme de soumission de formulaire dit exactement quelle requête doit être générée:

Spécifiquement pour php, j'ai fait quelques tests avec des noms de tableaux dans des entrées cachées et je partage ici mes résultats:

<!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>

La soumission du formulaire génère le résultat suivant:

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
)

Après avoir visionné ce résultat, j’ai fait plus de tests pour trouver un meilleur arrangement des valeurs de tableau et j’ai terminé par ceci (je ne montrerai que les nouvelles entrées cachées):

    <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">

obtenir ce résultat après avoir soumis le formulaire:

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
)

J'espère que cela aide quelques-uns.

2
Melo Waste

Je crois que c'est légal, au moins dans les cas de boutons radio et de cases à cocher. Lorsque je dois ajouter dynamiquement des entrées de zone de texte dans XSLT, je leur attribue le même nom. Dans ASP.NET, Request.Form ["Whatever_name"] est une chaîne de toutes ces valeurs séparées par une virgule. 

0
CaptainJanuary

Je viens d'essayer d'utiliser le même nom de contrôle, comtés [] pour plusieurs entrées SELECT, afin que les comtés d'Angleterre, d'Écosse, du Pays de Galles et d'Irlande soient tous passés en tant que valeurs du même paramètre. PHP s'en sort bien, mais le validateur HTML donne un avertissement. Je ne sais pas si tous les navigateurs géreraient cela de la même manière.

0
Nick Iredale