jQuery `submit` 方法忽略使用 GET 发送的 POST.为什么?

2021-12-29 00:00:00 forms jquery php javascript zend-framework

我有一个这样的表格.

<input type="hidden" id="HiddenFormInput" name="HiddenFormInput"></表单>

由可通过 https://[my-server]/my-controller/my-action/ 访问的网页生成,这也是表单指向的操作.>

在服务器端,我区分了 GETPOST 请求.页面显示清晰 (GET) 或根据表单的值显示某些结果 (POST).

当我使用 jQuery 提交表单时(我在这里没有使用 AJAX,只是提交表单),如本代码段所示,

$("#hiddenForm").submit();

然后 jQuery 似乎是用 GET 提交这个表单的,尽管它清楚地标记为用 POST 提交.即使是 alert($("#hiddenForm").attr("method")); 也总是产生 "post".但是,只有当页面已被 GET 加载时,才会发生这种不需要的行为.如果页面是通过 POST 来的,即表单至少已经提交过一次,那么一切都按预期进行.

更新

问题是一个普通的 preventDefault() 问题.触发提交的按钮有自己的功能.那是一个超链接.所以我有了这个动作链.

  1. 超链接到https://[my-server]/my-controller/my-action/#
  2. 使用操作https://[my-server]/my-controller/my-action/提交表单.

当然,这会导致在没有提交表单的情况下调用 GET.一旦我在页面 https://[my-server]/my-controller/my-action/# 上,超链接失去了它的功能.这就是为什么第二次尝试总是有效的原因,因为操作链减少到提交表单.

  1. 超链接到 https://[my-server]/my-controller/my-action/#(无效,因为已经存在)
  2. 使用操作https://[my-server]/my-controller/my-action/提交表单.

然后它当然起作用了.

解决方案

正如评论中所讨论的,没有错误,至少在 jQuery 2.0.3 的最后一个版本上,可以用这个来测试:

<头><script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script><脚本>$(document).ready(function () {$('#dosubmit').on('click',function(){$("#hiddenForm").submit();});});<身体><?php//如果(计数($_GET)> 0){echo "<textarea style="width: 700px;高度:90px;">提交方法=GET:$_GET:";var_dump($_GET);echo "</textarea>";}如果(计数($_POST)> 0){echo "<textarea style="width: 700px;高度:90px;">提交方法=POST:$_POST:";var_dump($_POST);echo "</textarea>";}?><form id="hiddenForm" method="post" enctype="multipart/form-data"><input type="hidden" id="HiddenFormInput" name="HiddenFormInput"/></表单><div id="dosubmit" style="background-color: gold; width: 200px; cursor: pointer;">点击我做jQuery提交</div>

当点击金色背景文字时,$("#hiddenForm").submit();用于提交表单.

这是输出:

提交方法=POST:$_POST:数组(1){["HiddenFormInput"]=>字符串(0)"}

在您的原始表单中,提交不会传递任何 URL 参数,因为仅提交具有指定 name 属性的输入.所以我为你的隐藏输入添加了属性 name="HiddenFormInput".

I have a form like this.

<form id="hiddenForm" method="post" action="/my-controller/my-action/" enctype="multipart/form-data">
    <input type="hidden" id="HiddenFormInput" name="HiddenFormInput">
</form>

which is produced by a web page accessible through https://[my-server]/my-controller/my-action/, which is also the action the form points to.

On the server side, I differentiate between GET and POST requests. Either the page is shown plainly (GET) or some results are shown depending on the form's values (POST).

When I use jQuery to submit the form (I am NOT employing AJAX here, simply submitting the form), as in this snippet,

$("#hiddenForm").submit();

then jQuery seems to submit this form with GET, although it's clearly marked to be submitted with POST. Even an alert($("#hiddenForm").attr("method")); always yields "post". However, this unwanted behaviour only occurs if the page has been loaded by a GET. If the page came by a POST, i.e. the form has already been submitted at least once, everything works just as expected.

Update

The problem was a plain old preventDefault() one. The button that triggered the submit had a functionality of its own. It was a hyperlink. So I had this chain of actions.

  1. Hyperlink to https://[my-server]/my-controller/my-action/#
  2. Submit form with action https://[my-server]/my-controller/my-action/.

Of course that would result in a GET call without the form being submitted. Once I was on the page https://[my-server]/my-controller/my-action/# the hyperlink lost it's functionality. That's why the second try always worked because the chain of actions was reduced to the submission of the form.

  1. Hyperlink to https://[my-server]/my-controller/my-action/# (no effect because already there)
  2. Submit form with action https://[my-server]/my-controller/my-action/.

Then it worked of course.

解决方案

As discussed in comments, there is no bug, at least on the last version of jQuery 2.0.3, one can test with this:

<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script>
$(document).ready(function () {
  $('#dosubmit').on('click',function(){
    $("#hiddenForm").submit();
  });
});
</script>
</head>
<body>

<?php
//
if(count($_GET) > 0) {
  echo "<textarea style="width: 700px; height: 90px;">
Submitted with method=GET: $_GET:
";
  var_dump($_GET);
  echo "</textarea>";
}

if(count($_POST) > 0) {
echo "<textarea style="width: 700px; height: 90px;">
Submitted with method=POST: $_POST:
";
  var_dump($_POST);
  echo "</textarea>";
}
?>

<form id="hiddenForm" method="post" enctype="multipart/form-data">
  <input type="hidden" id="HiddenFormInput" name="HiddenFormInput" />
</form>

<div id="dosubmit" style="background-color: gold; width: 200px; cursor: pointer;">Click me to Do jQuery Submit</div>

</body>
</html>

When one clicks on gold background text, $("#hiddenForm").submit(); is used to submit the form.

Here is the output:

Submitted with method=POST: $_POST:
array(1) {
  ["HiddenFormInput"]=>
    string(0) ""
}

In your original form, no URL arguments are passed by the submitting, as only inputs with name attribute specified are submitted. So I added the attribute name="HiddenFormInput" for your hidden input.

相关文章