【问题标题】:When submitting a GET form, the query string is removed from the action URL提交 GET 表单时,查询字符串会从操作 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 的可能解决方法:stackoverflow.com/questions/3548795/…
  • 我在 android webview 中也发生了同样的事情。

标签: html forms http-get


【解决方案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”。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-06-18
              • 2011-02-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多