考虑这个形式:

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

当提交这个GET表单时,参数a和b将消失。 这有什么原因吗? 有没有办法避免这种行为?


当前回答

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

其他回答

我的观察

当方法为GET并提交表单时,隐藏的输入元素作为查询参数发送。旧参数在行动url被清除。基本上在这个例子中,表单数据取代了action url中的查询字符串 当方法是POST,并且提交表单时,action url中的查询参数是完整的(req.query)并且输入元素数据作为表单数据发送(req.body)

简单来说,如果你想传递查询参数和表单数据,使用方法属性POST

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

将请求方法改为' POST'而不是'GET'。

回答你的第一个问题,是的,浏览器会这样做,原因是 浏览器并不关心动作URL中的现有参数 所以它会完全去除它们

为了防止这种情况发生使用我写的JavaScript函数 使用jQuery:

function addQueryStringAsHidden(form){
    if (form.attr("action") === undefined){
        throw "form does not have action attribute"
    }

    let url = form.attr("action");
    if (url.includes("?") === false) return false;
    
    let index = url.indexOf("?");
    let action = url.slice(0, index)
    let params = url.slice(index);
    url = new URLSearchParams(params);
    for (param of url.keys()){
        let paramValue = url.get(param);
        let attrObject = {"type":"hidden", "name":param, "value":paramValue};
        let hidden = $("<input>").attr(attrObject);
        form.append(hidden);
    }
    form.attr("action", action)
}

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

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

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

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

<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”内容类型编码的表单数据集。

也许可以对action-URL进行百分比编码,以嵌入问号和参数,然后祈祷所有浏览器都能保留该URL(并验证服务器也能理解它)。但我绝不会依赖于此。

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