When submitting a GET form, the query string is removed from the action URL

HtmlFormsHttp Get

Html Problem Overview


Consider this form:

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

When submitting this GET form, the parameters a and b are disappearing.
Is there a reason for that?
Is there a way of avoiding this behaviour?

Html Solutions


Solution 1 - Html

Isn't that what hidden parameters are for to start with...?

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

I wouldn't count on any browser retaining any existing query string in the action URL.

As the specifications (RFC1866, page 46; HTML 4.x section 17.13.3) state:

> If the method is "get" and the action is an HTTP URI, the user agent takes the value of action, appends a `?' to it, then appends the form data set, encoded using the "application/x-www-form-urlencoded" content type.

Maybe one could percent-encode the action-URL to embed the question mark and the parameters, and then cross one's fingers to hope all browsers would leave that URL as it (and validate that the server understands it too). But I'd never rely on that.

By the way: it's not different for non-hidden form fields. For POST the action URL could hold a query string though.

Solution 2 - Html

In HTML5, this is per-spec behaviour.

See Association of controls and forms - Form submission algorithm.

Look at "4.10.22.3 Form submission algorithm", step 17. In the case of a GET form to an http/s URI with a query string:

> Let destination be a new URL that is equal to the action except that > its <query> component is replaced by query (adding a U+003F QUESTION > MARK character (?) if appropriate).

So, your browser will trash the existing "?..." part of your URI and replace it with a new one based on your form.

In HTML 4.01, the spec produces invalid URIs - most browsers didn't actually do this though...

See Forms - Processing form data, step four - the URI will have a ? appended, even if it already contains one.

Solution 3 - Html

What you can do is using a simple foreach on the table containing the GET information. For example in PHP :

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

As the GET values are coming from the user, we should escape them before printing on screen.

Solution 4 - Html

You should include the two items (a and b) as hidden input elements as well as C.

Solution 5 - Html

I had a very similar problem where for the form action, I had something like:

<form action="http://www.example.com/?q=content/something" method="GET">
   <input type="submit" value="Go away..." />&nbsp;
</form>

The button would get the user to the site, but the query info disappeared so the user landed on the home page rather than the desired content page. The solution in my case was to find out how to code the URL without the query that would get the user to the desired page. In this case my target was a Drupal site, so as it turned out /content/something also worked. I also could have used a node number (i.e. /node/123).

Solution 6 - Html

If you need workaround, as this form can be placed in 3rd party systems, you can use Apache mod_rewrite like this:

RewriteRule ^dummy.link$ index.php?a=1&b=2 [QSA,L]

then your new form will look like this:

<form ... action="http:/www.blabla.com/dummy.link" method="GET">
<input type="hidden" name="c" value="3" /> 
</form>

and Apache will append 3rd parameter to query

Solution 7 - Html

When the original query has array, for 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";
}

Solution 8 - Html

To answer your first question yes the browser does that and the reason is that the browser does not care about existing parameters in the action URL so it removes them completely

and to prevent this from happening use this JavaScript function that I wrote using jQuery in:

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

Solution 9 - Html

This is in response to the above post by Efx:

If the URL already contains the var you want to change, then it is added yet again as a hidden field.

Here is a modification of that code as to prevent duplicating vars in the URL:

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

Solution 10 - Html

Your construction is illegal. You cannot include parameters in the action value of a form. What happens if you try this is going to depend on quirks of the browser. I wouldn't be surprised if it worked with one browser and not another. Even if it appeared to work, I would not rely on it, because the next version of the browser might change the behavior.

"But lets say I have parameters in query string and in hidden inputs, what can I do?" What you can do is fix the error. Not to be snide, but this is a little like asking, "But lets say my URL uses percent signs instead of slashes, what can I do?" The only possible answer is, you can fix the URL.

Solution 11 - Html

I usually write something like this:

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

This is working, but don't forget to sanitize your inputs against XSS attacks!

Solution 12 - Html

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

change the request method to' POST' instead of 'GET'.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionView Question on Stackoverflow
Solution 1 - HtmlArjanView Answer on Stackoverflow
Solution 2 - HtmlxyphoidView Answer on Stackoverflow
Solution 3 - HtmlEfxView Answer on Stackoverflow
Solution 4 - HtmlBernhard HofmannView Answer on Stackoverflow
Solution 5 - HtmlKillerRabbitView Answer on Stackoverflow
Solution 6 - HtmlwanisView Answer on Stackoverflow
Solution 7 - HtmlDaniel-KMView Answer on Stackoverflow
Solution 8 - HtmlMRE20View Answer on Stackoverflow
Solution 9 - HtmlTH_View Answer on Stackoverflow
Solution 10 - HtmlJayView Answer on Stackoverflow
Solution 11 - HtmlRápli AndrásView Answer on Stackoverflow
Solution 12 - HtmlShashidhar GrView Answer on Stackoverflow