отправка формы GET с параметрами строки запроса и скрытыми параметрами исчезает

231

Рассмотрим эту форму:

<form action="http://www.blabla.com?a=1&b=2" method="GET">
    <input type="hidden" name="c" value="3" /> 
</form>

При отправке этой формы (формы GET) параметры a и b исчезают. Есть ли причина для этого? Есть ли способ избежать этого поведения?

Kiquenet
источник
3
Ваш элемент действия искажен.
Адриан Годонг
Они не должны исчезнуть, поэтому я думаю, что нам нужно увидеть вашу форму.
UnkwnTech
2
Привет, вот полная форма, вы можете просто создать HTML с этой формой и увидеть, что параметры, которые я передаю в действии, не отображаются: <form action = " example.com?e=4&f=5 " method = "GET"> <input type = "hidden" name = "a" value = "1" /> <input type = "hidden" name = "b" value = "2" /> <input type = "hidden" name = "c" value = "3" /> <input type = "submit" /> </ form>
1
Кстати, вы знаете, что вам не хватает конечной кавычки для значения этого действия? Абсолютно в стороне от основной проблемы, но ...
Джей
Я разместил возможный обходной путь с использованием JavaScript здесь: stackoverflow.com/questions/3548795/…
Дженни О'Рейли,

Ответы:

263

Разве не для этого нужны скрытые параметры ...?

<form action="http://www.example.com" method="GET">
  <input type="hidden" name="a" value="1" /> 
  <input type="hidden" name="b" value="2" /> 
  <input type="hidden" name="c" value="3" /> 
  <input type="submit" /> 
</form>

Я бы не стал рассчитывать, что какой-либо браузер сохранит существующую строку запроса в URL-адресе действия.

В спецификациях ( RFC1866 , стр. 46; HTML 4.x раздел 17.13.3) указано:

Если метод "get" и действие является HTTP URI, пользовательский агент принимает значение action и добавляет `? ' к нему затем добавляется набор данных формы, закодированный с использованием типа контента application / x-www-form-urlencoded.

Возможно, кто-то может кодировать URL-адрес действия для встраивания знака вопроса и параметров, а затем скрестить пальцы, надеясь, что все браузеры оставят этот URL-адрес таким (и подтвердит, что сервер его тоже понимает). Но я бы никогда не положился на это.

Кстати, это не отличается для не скрытых полей формы. Для POST URL действия может содержать строку запроса.

Арьян
источник
71

В HTML5 это поведение для каждой спецификации.

См. Http://www.w3.org/TR/2011/WD-html5-20110525/association-of-controls-and-forms.html#form-submission-algorithm

Посмотрите на «4.10.22.3 Алгоритм отправки формы», шаг 17. В случае формы GET для URI http / s со строкой запроса:

Пусть destination будет новый URL-адрес, равный действию, за исключением того, что его <query>компонент заменен запросом (при необходимости добавляя символ U + 003F QUESTION MARK (?)).

Итак, ваш браузер удалит существующую часть «? ...» в вашем URI и заменит ее новой на основе вашей формы.

В HTML 4.01 спецификация создает недопустимые URI - хотя большинство браузеров на самом деле этого не делают ..

См. Http://www.w3.org/TR/html401/interact/forms.html#h-17.13.3 , шаг четвертый - URI будет иметь? добавлен, даже если он уже есть.

xyphoid
источник
это значит: все, что находится ?в действии, будет удалено? Так что же, если параметр GET в URL-адресе действия содержит цель, где должна обрабатываться форма? нравится: action="index.php?site=search". Я не уверен, если поместить параметр GET в скрытые поля ввода - это божественная идея.
Bndr
что вы подразумеваете под per-spec @xyphoid?
AmiNadimi
@AmiNadimi: Это означает «в соответствии со спецификацией».
рекурсивный
14

То, что вы можете сделать, это использовать простой foreach для таблицы, содержащей информацию GET. Например в php:

foreach ($_GET as $key => $value) {
    echo("<input type='hidden' name='$key' value='$value'/>");
}
Efx
источник
23
Примечание: никогда не используйте этот пример кода точно так, как написано. Это было бы очень опасно. Значения из GET исходят от пользователя, поэтому их не следует записывать на страницу без их экранирования.
Дрюм
16
Понижение до исправления ошибки XSS в этом коде.
spookylukey
1
Этот ответ обеспечивает аналогичное решение, но не является уязвимым для XSS.
vvzh
это не обрабатывает параметры массива
Эндрю
5

Вы должны включить два элемента (a и b) в качестве скрытых элементов ввода, а также C.

Бернхард Хофманн
источник
Да, конечно, я бы сделал это, если это возможно. Но допустим, у меня есть параметры в строке запроса и в скрытых входах, что я могу сделать?
Я думаю, что ваш единственный вариант - это анализ пар имя / значение строки запроса и создание скрытых полей ввода. Возможно, если бы вы описали немного больше вокруг контекста страницы и URL, мы могли бы предложить рабочее решение.
Бернхард Хофманн
Или же возьмите данные из скрытых элементов формы и добавьте их в URL-адрес и дополнительные параметры запроса, затем замените кнопку отправки формы простой привязкой или Location:перенаправлением на сервер, если вы не хотите никакого взаимодействия с конечным пользователем. ,
Джейсон
1

У меня была очень похожая проблема, когда для действия формы у меня было что-то вроде:

<form action="http://www.example.com/?q=content/something" method="GET">
   <input type="submit" value="Go away..." />&nbsp;
</form>

Кнопка доставит пользователя на сайт, но информация о запросе исчезла, поэтому пользователь попал на домашнюю страницу, а не на нужную страницу контента. Решение в моем случае состояло в том, чтобы выяснить, как закодировать URL-адрес без запроса, который приведет пользователя к нужной странице. В этом случае моей целью был сайт Drupal, так что, как оказалось, это /content/somethingтоже сработало. Я также мог бы использовать номер узла (то есть /node/123).

KillerRabbit
источник
0

Если вам нужен обходной путь, поскольку эту форму можно разместить в сторонних системах, вы можете использовать Apache mod_rewrite следующим образом:

RewriteRule ^dummy.link$ index.php?a=1&b=2 [QSA,L]

тогда ваша новая форма будет выглядеть так:

<form ... action="http:/www.blabla.com/dummy.link" method="GET">
<input type="hidden" name="c" value="3" /> 
</form>

и Apache добавит 3-й параметр к запросу

Wanis
источник
-3

Ваше строительство незаконно. Вы не можете включить параметры в значение действия формы. Что произойдет, если вы попытаетесь это сделать, будет зависеть от особенностей браузера. Я не удивлюсь, если он работает с одним браузером, а не с другим. Даже если бы это работало, я бы не стал полагаться на это, потому что следующая версия браузера может изменить поведение.

«Но допустим, у меня есть параметры в строке запроса и в скрытых входах, что я могу сделать?» Что вы можете сделать, это исправить ошибку. Не быть глупым, но это немного похоже на вопрос: «Но допустим, что мой URL использует знаки процента вместо косой черты, что я могу сделать?» Единственный возможный ответ - вы можете исправить URL.

сойка
источник
Весь этот ответ является технически правильным («это неправильно, так что исправьте его»), но он бесполезен. ОП уже знает, что что-то не так, и здесь спрашивает, как это исправить.
Джейсон
Простите, разве это не ясно? «Вы не можете включить параметры в значение действия формы». Чтобы исправить это, удалите параметры из значения действия формы.
Джей
@Jay Проблема состоит в том, что пользователю нужны параметры URL, чтобы остаться, поэтому, говоря, «удалить их» не поможет
Чак Ле Батт
@ChuckLeButt Говорить «но мне нужно сделать то, что не работает», не очень полезно. Если кто-то говорит мне: «Я продолжаю поворачивать ручку радио, но моя машина не двигается», единственный ответ, который я могу придумать, - это сказать: «Поворот ручки радио не приводит машину в движение. ключ зажигания и нажмите на педаль газа. " Ответить «но мне нужно, чтобы машина двигалась поворотом радиоприемника», - непродуктивный ответ. Это не работает Это не сработает.
Джей
-3

Это в ответ на вышеупомянутый пост Efx:

Если URL-адрес уже содержит переменную, которую вы хотите изменить, он снова добавляется как скрытое поле.

Вот модификация этого кода, чтобы предотвратить дублирование переменных в URL:

foreach ($_GET as $key => $value) {
    if ($key != "my_key") {
        echo("<input type='hidden' name='$key' value='$value'/>");
    }
}
TH_
источник
-4
<form ... action="http:/www.blabla.com?a=1&b=2" method ="POST">
<input type="hidden" name="c" value="3" /> 
</form>

измените метод запроса на «POST» вместо «GET».

Шашидхар Гр
источник
-4

Я обычно пишу что-то вроде этого:

foreach($_GET as $key=>$content){
        echo "<input type='hidden' name='$key' value='$content'/>";
}

Это работает, но не забывайте очищать свои входные данные от атак XSS!

Рапли Андраш
источник