269

考虑这种形式:

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

提交此GET表单时,参数ab正在消失。
这有什么原因吗?
有没有办法避免这种行为?

4

11 回答 11

304

这不就是隐藏参数的开始......吗?

<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 可以保存一个查询字符串。

于 2009-07-12T13:15:19.890 回答
83

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

请参阅控件和表单的关联 - 表单提交算法

查看“4.10.22.3 表单提交算法”,第 17 步。在 GET 表单到http/s带有查询字符串的 URI 的情况下:

让destination 是一个新的URL,它与动作相同,只是它的<query>组件被查询替换(如果合适,添加一个U+003FQUESTION MARK 字符)。(?)

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

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

请参阅表单 - 处理表单数据,第四步 - URI 将?附加一个,即使它已经包含一个。

于 2012-03-27T02:53:32.810 回答
14

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

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

由于 GET 值来自用户,我们应该在屏幕上打印之前转义它们。

于 2012-01-06T19:53:10.810 回答
5

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

于 2009-07-12T13:16:10.903 回答
0

我有一个非常相似的问题,对于表单操作,我有类似的东西:

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

于 2011-09-07T17:26:24.533 回答
0

如果您需要解决方法,因为此表单可以放置在 3rd 方系统中,您可以像这样使用 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 将附加第三个参数来查询

于 2013-05-07T09:36:13.143 回答
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";
}
于 2021-06-29T10:28:21.757 回答
-2

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

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

于 2011-09-07T17:45:13.697 回答
-2

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

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

这是对该代码的修改,以防止在 URL 中重复 var:

foreach ($_GET as $key => $value) {
    if ($key != "my_key") {
        echo("<input type='hidden' name='$key' value='$value'/>");
    }
}
于 2015-04-14T22:36:46.653 回答
-3

我通常会这样写:

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

这是有效的,但不要忘记清理您的输入以防止 XSS 攻击!

于 2014-02-16T01:02:50.407 回答
-4
<form ... action="http:/www.blabla.com?a=1&b=2" method ="POST">
<input type="hidden" name="c" value="3" /> 
</form>

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

于 2013-09-07T07:29:37.157 回答