提交 GET 表单时,查询字符串会从操作 URL 中删除

Posted

技术标签:

【中文标题】提交 GET 表单时,查询字符串会从操作 URL 中删除【英文标题】:When submitting a GET form, the query string is removed from the action URL 【发布时间】:2010-11-10 02:28:25 【问题描述】:

考虑这种形式:

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

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

【问题讨论】:

他们不应该消失,所以我想我们需要看看你的表格。 嗨,这是完整的表单,您可以使用此表单创建一个 html,然后看到我在操作中传递的参数消失了:
example.com?e=4&f=5" method="GET ">
我在这里发布了一个使用 javascript 的可能解决方法:***.com/questions/3548795/… 我在 android webview 中也发生了同样的事情。 【参考方案1】:

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

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

【讨论】:

@Rob,我恢复了你的编辑;问题是关于隐藏参数的。【参考方案2】:

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

见Association of controls and forms - Form submission algorithm。

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

设destination是一个新的URL,它与动作相同,除了 它的&lt;query&gt; 组件被查询替换(添加一个U+003F QUESTION 标记字符(?)(如果适用)。

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

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

参见Forms - Processing form data,第四步 - URI 将附加一个 ?,即使它已经包含一个。

【讨论】:

这意味着:动作 url 中? 后面的所有内容都被删除了吗?那么,如果 action url 中的 GET 参数包含目标,表单应该在哪里处理呢?喜欢:action="index.php?site=search"。我不确定,如果将 GET 参数放在隐藏的输入字段中是个好主意。 每个规格@xyphoid 是什么意思? @AmiNadimi:意思是“按照规范”。【参考方案3】:

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

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

由于 GET 值来自用户,我们应该在打印到屏幕之前对其进行转义。

【讨论】:

这不处理数组参数【参考方案4】:

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

【讨论】:

是的,如果可能的话,我当然会这样做。但是假设我在查询字符串和隐藏输入中有参数,我该怎么办? 我认为您唯一的选择是解析查询字符串名称/值对并生成隐藏的输入字段。如果您对页面和 URL 的上下文进行更多描述,也许我们可以提出一个可行的解决方案。 或者,从隐藏的表单项中获取数据,并将它们添加到 URL 和其他查询参数中,然后将表单提交按钮替换为简单的锚链接,或者服务器 Location: 重定向如果您不希望与最终用户进行任何交互。【参考方案5】:

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

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

【讨论】:

【参考方案6】:

如果您需要解决方法,因为此表单可以放置在 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 会在查询中追加第三个参数

【讨论】:

【参考方案7】:

当原始查询有数组时,对于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】:

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

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

【讨论】:

这整个答案在技术上是正确的(“它错了,所以修复它”)但没有任何用处。 OP 已经知道出了问题,并在这里询问如何解决它。 对不起,不是很清楚吗? “您不能在表单的操作值中包含参数。”要修复它,请从表单的操作值中删除参数。 @Jay 问题显然是用户需要保留 URL 参数,所以说“删除它们”是没有用的 @ChuckLeButt 说“但我需要做这件行不通的事情”并不是一个有用的说法。如果有人告诉我,“我一直在转动收音机旋钮,但我的车不动”,我能想到的唯一反应就是说,“转动收音机旋钮不会让车动。你必须转动点火钥匙并踩下油门踏板。”回答“但我需要通过转动收音机旋钮来让汽车移动”是一种徒劳的回答。它不起作用。它不会起作用。【参考方案9】:

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

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

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

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

【讨论】:

【参考方案10】:

我通常会这样写:

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

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

【讨论】:

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

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

【讨论】:

以上是关于提交 GET 表单时,查询字符串会从操作 URL 中删除的主要内容,如果未能解决你的问题,请参考以下文章

在 JSF 表单提交上保留 GET 请求查询字符串参数

表单提交中get和post方式的区别

表单的提交有两种方式:GET和POST,这两种方式的区别是啥?

从 url 中删除搜索查询而不刷新页面?

php 过滤以在提交或重定向时从URL中删除联系表单7查询字符串。进入函数文件。

如何在表单提交期间删除 URL 中的特殊字符