jQuery `submit` method ignores POST sends with GET

2020-04-08 12:20发布

问题:

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.

回答1:

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.