提交带有查询字符串参数的GET表单和隐藏的参数消失

时间:2009-07-12 13:09:36

标签: html forms submit

请考虑以下形式:

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

提交此表格(GET表格)时,参数a和b正在消失。 这有什么理由吗? 有没有办法避免这种行为?

11 个答案:

答案 0 :(得分:236)

这不是隐藏参数的开头......?

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

我不会指望任何浏览器在动作网址中保留任何现有的查询字符串。

根据规范(RFC1866,第46页; HTML 4.x第17.13.3节)声明:

  

如果方法是“get”并且操作是HTTP URI,则用户代理获取action的值,附加“?”然后,使用“application / x-www-form-urlencoded”内容类型附加表单数据集。

也许有人可以对action-URL进行百分比编码以嵌入问号和参数,然后交叉指示希望所有浏览器都将该URL留下(并验证服务器是否也理解它)。但我永远不会依赖它。

顺便说一句:对于非隐藏的表单字段,它没有什么不同。对于POST,操作URL可以包含查询字符串。

答案 1 :(得分:66)

在HTML5中,这是符合规范的行为。

请参阅http://www.w3.org/TR/2011/WD-html5-20110525/association-of-controls-and-forms.html#form-submission-algorithm

查看“4.10.22.3表单提交算法”,步骤17.对于带有查询字符串的http / s URI的GET表单:

  

让目标成为一个新的URL,除了它之外的行为   其<query>组件被查询替换(添加U + 003F问题   如果合适的话,标记字符(?)。

因此,您的浏览器会废弃URI的现有“?...”部分,并根据您的表单将其替换为新的。

在HTML 4.01中,规范产生了无效的URI - 大多数浏览器实际上并没有这样做..

请参阅http://www.w3.org/TR/html401/interact/forms.html#h-17.13.3,第四步 - URI会有一个?附加,即使它已经包含一个。

答案 2 :(得分:16)

您可以做的是在包含GET信息的表上使用简单的foreach。例如在php:

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

答案 3 :(得分:5)

您应该将两个项目(a和b)包含为隐藏的输入元素以及C。

答案 4 :(得分: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)。

答案 5 :(得分:1)

你的建筑是非法的。您不能在表单的操作值中包含参数。如果您尝试这样做会发生什么取决于浏览器的怪癖。如果它适用于一个浏览器而不是另一个浏览器,我不会感到惊讶。即使它似乎有效,我也不会依赖它,因为浏览器的下一个版本可能会改变行为。

“但是我可以说我在查询字符串和隐藏输入中有参数,我该怎么办?”你能做的就是修复错误。不要嗤之以鼻,但这有点像问,“但是我可以说我的URL使用百分号而不是斜线,我该怎么办?”唯一可能的答案是,您可以修复网址。

答案 6 :(得分: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个参数进行查询

答案 7 :(得分:0)

当原始查询有数组时,对于php:

foreach (explode("\n", http_build_query($query, '', "\n")) as $keyValue) {
    [$key, $value] = explode('=', $keyValue, 2);
    $key = htmlspecialchars(urldecode($key), ENT_COMPAT | ENT_HTML5);
    $value = htmlspecialchars(urldecode($value), ENT_COMPAT | ENT_HTML5);
    echo '<input type="hidden" name="' . $key . '" value="' . $value . '"' . "/>\n";
}

答案 8 :(得分:-2)

这是对Efx的上述帖子的回应:

如果网址已包含您要更改的var,则会再次将其添加为隐藏字段。

以下是对该代码的修改,以防止重复URL中的变量:

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

答案 9 :(得分:-4)

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

将请求方法更改为“POST”而不是“GET”。

答案 10 :(得分:-4)

我经常写这样的东西:

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

这是有效的,但不要忘记对XSS攻击的输入进行消毒!