43

Basically, I think that I can't, but I would be very happy to be proven wrong.

I am generating an HTML menu dynamically in PHP, adding one item for each current user, so that I get something like <a href="process_user.php?user=<user>>, but I have a preference for POST over GET.

Is there a way to pass the information as a POST parameter, rather than GET from a clickable HREF link?

I am not allowed to use JavaScript.


It looks like Rob is on to something with "You could use a button instead of an anchor and just style the button to look like a link. That way you could have your values in hidden fields inside the same form to be sent via POST"

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551
  • 3
    You use a form or javascript ajax., sorry no way to pass post in url – Ibu Jun 02 '11 at 05:46
  • 1
    only one solution : [jQuery.Ajax()](http://api.jquery.com/jQuery.ajax/) – xkeshav Jun 02 '11 at 05:49
  • 2
    What does "process_user" do? Does it update/create info or just search? – Mr Meow Jun 02 '11 at 05:51
  • 1
    You could use a button instead of an anchor and just style the button to look like a link. That way you could have your values in hidden fields inside the same form to be sent via POST. – Ben Jun 02 '11 at 05:52
  • 1
    In addition to what Ben said, you can also let the link be a dummy and have it execute a javascript that submits a hidden form. As forms can be a bit picky on how they are nested, this might make it easier. – Battle_707 Jun 02 '11 at 05:58
  • "You could use a button instead of an anchor and just style the button to look like a link. That way you could have your values in hidden fields inside the same form to be sent via POST" ... @Ben, me like !!! It's 11:30 & I just got home (hic) ... can you post that as an answer (and elaborate?) It sounds extremely promising – Mawg says reinstate Monica Jun 02 '11 at 15:04
  • Petah below beat my to it @Mawg but I'm glad you have found a solution. Good luck. – Ben Jun 03 '11 at 15:16
  • I wrote a POST forwarder page few days back which does something like this, though it uses javascript of course ... http://loknar.github.io/postforwarder/ – Loknar Mar 23 '16 at 14:01

7 Answers7

49

You could use a form styled as a link. No JavaScript is required:

<form action="/do/stuff.php" method="post">
    <input type="hidden" name="user_id" value="123" />
    <button>Go to user 123</button>
</form>

CSS:

button {
    border: 0;
    padding: 0;
    display: inline;
    background: none;
    text-decoration: underline;
    color: blue;
}
button:hover {
    cursor: pointer;
}

See: http://jsfiddle.net/SkQRN/

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Petah
  • 45,477
  • 28
  • 157
  • 213
  • 2
    This works. Just to add if he wanted the link to be consistent with his other links, he might add it in his stylesheet as `a:link, button.class {}`, and `a:hover, button.class:hover {}`, etc. – Rob Jun 02 '11 at 05:57
  • 5
    ...and you can still set `method='post'` to the form, if you like. Great! – Alphaaa May 23 '15 at 05:17
15

Parameters in the URL are GET parameters, a request body, if present, is POST data. So your basic premise is by definition not achievable.

You should choose whether to use POST or GET based on the action. Any destructive action, i.e. something that permanently changes the state of the server (deleting, adding, editing) should always be invoked by POST requests. Any pure "information retrieval" should be accessible via an unchanging URL (i.e. GET requests).

To make a POST request, you need to create a <form>. You could use Javascript to create a POST request instead, but I wouldn't recommend using Javascript for something so basic. If you want your submit button to look like a link, I'd suggest you create a normal form with a normal submit button, then use CSS to restyle the button and/or use Javascript to replace the button with a link that submits the form using Javascript (depending on what reproduces the desired behavior better). That'd be a good example of progressive enhancement.

deceze
  • 510,633
  • 85
  • 743
  • 889
13

You can make a link perform an Ajax post request when it's clicked.

In jQuery:

$('a').click(function(e) {
    var $this = $(this);
    e.preventDefault();
    $.post('url', {'user': 'something', 'foo': 'bar'}, function() {
        window.location = $this.attr('href');
    });
});

You could also make the link submit a POST form with JavaScript:

<form action="url" method="post">
    <input type="hidden" name="user" value="something" />
    <a href="#">CLick</a>
</form>

<script>
    $('a').click(function(e) {
        e.preventDefault();
        $(this).parents('form').submit();
    });
</script>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rob
  • 1,865
  • 1
  • 14
  • 26
7

I would like to share my implementation as well. It does require some JavaScript code though.

<form action="./index.php" id="homePage" method="post" style="display: none;">
    <input type="hidden" name="action" value="homePage" />
</form>

<a href="javascript:;" onclick="javascript:
document.getElementById('homePage').submit()">Home</a>

The nice thing about this is that, contrary to GET requests, it doesn't show the parameters in the URL, which is safer.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Aris
  • 4,643
  • 1
  • 41
  • 38
7

No, you cannot do that. I invite you to read a POST definition.

Or this page: HTTP, request methods

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
zzarbi
  • 1,832
  • 3
  • 15
  • 29
  • 1
    Though you link to some informative articles, it actually is possible with some JavaScript or CSS as shown in other answers. – Rob Jun 02 '11 at 06:00
  • 2
    You question is "How to pass POST parameters in a URL ?" the answer is your CANNOT. The previous code is to send POST variables through a form via a javascript event... – zzarbi Jun 02 '11 at 06:03
  • 3
    That was the title of the question. If you read the actual question, he was looking for something different. – Rob Jun 02 '11 at 06:05
  • 2
    "Is there any way to pass the info as a POST parameter, rather than GET from a clickable HREF link?" as a clickable LINK... we can play on word I agree that you can hack around it but it's not a link anymore, it's an action. – zzarbi Jun 02 '11 at 06:11
  • ok, alright, already ... a clickable anything (which the user might think is a link, would be a bonus) It looks like @rob has an idea with submit buttons – Mawg says reinstate Monica Jun 02 '11 at 15:06
  • This is not much more than RTFM. Can you provide a summary and/or an actual argument for why not in the answer? (***Without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today.) – Peter Mortensen Feb 09 '21 at 23:19
5

First off, a disclaimer: I don't think marrying POST with URL parameters is a brilliant idea. Like others suggested, you're better off using a hidden form for passing user information.

However, a question made me curious how PHP is handling such a case. It turned out that it's possible in theory. Here's a proof:

post_url_params.html

<!DOCTYPE html>
<html>
    <head></head>
    <body>
        <form method="post" action="post_url_params.php?key1=value1">
            <input type="hidden" name="key2" value="value2">
            <input type="hidden" name="key3" value="value3">
            <input type="submit" value="click me">
        </form>
    </body>
</html>

post_url_params.php

<?php
    print_r($_POST);
    print_r($_GET);
    echo $_SERVER['REQUEST_METHOD'];
?>

Output

Array ( [key2] => value2 [key3] => value3 )
Array ( [key1] => value1 )
POST

One can clearly see that PHP stores URL parameters in the $_GET variable and form data in the $_POST variable. I suspect it's very PHP- and server-specific, though, and is definitely not a thing to rely on.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
raiks
  • 1,270
  • 1
  • 15
  • 12
2

This could work if the PHP script generates a form for each entry with hidden fields and the href uses JavaScript to post the form.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
tofutim
  • 22,664
  • 20
  • 87
  • 148