HTML-форма с несколькими скрытыми одноименными элементами управления.
-
19-08-2019 - |
Вопрос
Законно ли иметь HTML-форму с более чем одним «скрытым» элементом управления с одинаковым именем?Я ожидаю получить значения всех этих элементов на сервере.Если это законно, правильно ли реализуют такое поведение основные браузеры?
Решение
Браузеры с этим согласны. Однако то, как библиотека приложения анализирует его, может отличаться.
Программы должны объединять элементы с одинаковыми именами. Хотя спецификация HTML прямо не говорит об этом, она неявно указана в документация по флажкам :
Несколько флажков в форме могут совместно использоваться то же имя элемента управления. Таким образом, для Например, флажки позволяют пользователям выберите несколько значений для одного и того же свойство.
Другие советы
Различные технологии на стороне сервера могут отличаться. С помощью 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 это немного отличается (как указывает Джонатан, нотация в скобках представляет элементы в виде массива для вашего кода 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 [" независимо от имени "] - это строка всех этих значений, разделенных запятыми. Р>
Я только что попытался использовать одно и то же управляющее имя, графства [] для нескольких входов SELECT, чтобы все графства в Англии, Шотландии, Уэльсе и Ирландии в каждом передавались как значения одного и того же параметра. PHP справляется, но HTML-валидатор выдает предупреждение. Я не знаю, будут ли все браузеры обрабатывать это одинаково.