265

Basically what I want to do is send POST data when I change the window.location, as if a user has submitted a form and it went to a new page. I need to do it this way because I need to pass along a hidden URL, and I can’t simply place it in the URL as a GET for cosmetic reasons.

This is what I have at the moment, but it doesn’t send any POST data.

if(user has not voted) {

    window.location = 'http://example.com/vote/' + Username;

}

I know that you can send POST data with jQuery.post(), but I need it to be sent with the new window.location.

So to recap, I need to send api_url value via POST to http://example.com/vote/, while sending the user to the same page at the same time.


For future reference, I ended up doing the following:

if(user has not voted) {

    $('#inset_form').html('<form action="http://example.com/vote/' + Username + '" name="vote" method="post" style="display:none;"><input type="text" name="api_url" value="' + Return_URL + '" /></form>');

    document.forms['vote'].submit();

}
0

10 Answers 10

261

per @Kevin-Reid's answer, here's an alternative to the "I ended up doing the following" example that avoids needing to name and then lookup the form object again by constructing the form specifically (using jQuery)..

var url = 'http://example.com/vote/' + Username;
var form = $('<form action="' + url + '" method="post">' +
  '<input type="text" name="api_url" value="' + Return_URL + '" />' +
  '</form>');
$('body').append(form);
form.submit();
12
  • 9
    I prefer this method over Kevin's method because you don't have to add a form to the html. The reason I wanted to do this was that I had a form already and nested another form inside of it. For some reason my main form decided to stop where the other began, ignoring all of the inputs that followed. I know this shouldn't happen, but there you go. The above method is nice when you want to 'redirect' with POST data from a piece of JS. Although I can't really shake feeling dirty when I do it this way ;).
    – Mosselman
    Commented Oct 26, 2012 at 8:48
  • 4
    Note that $(form) on the last line is redundant.
    – Joe
    Commented May 10, 2013 at 15:40
  • 9
    Just to add, current approach would display form for a fraction of a second on the "UI" before submitting. Just to make it perfect, add 'style' attribute to the form tag with value 'display: none;' . Commented Aug 15, 2013 at 23:56
  • 7
    As long as there's no style on the form element (borders, margins and whatnot) you can use type="hidden" instead. Commented Nov 25, 2013 at 19:01
  • 3
    I found that $('body').append(form); was very necessary in IE browsers!
    – Thomas
    Commented Jun 27, 2014 at 9:12
192

Construct and fill out a hidden method=POST action="http://example.com/vote" form and submit it, rather than using window.location at all.

4
  • 6
    Is there any way to do this using an nested object? Say I need the data {"a":{"b":"c"}} passed along. Is there a way to that with a form?
    – Akhil F
    Commented Nov 24, 2014 at 21:45
  • 7
    @AakilFernandes You can always JSON.stringify your object and put the resulting string into a form field. You can't send an arbitrary POST content type that a form wouldn't otherwise support.
    – Kevin Reid
    Commented Nov 24, 2014 at 22:05
  • but what if there is a <form> already? what can be done since form tags cannot be nested?? Commented Jul 4, 2017 at 7:44
  • 3
    @Malky.Kid do it as you would normally with a form, for example (using @AakilFernandes' data) you'd create <input type="hidden" name="a[b]" value="c"> within the form where "b" is a property of "a" with value "c". Commented Aug 6, 2017 at 14:27
62

Here's a simple small function that can be applied anywhere as long as you're using jQuery.

var redirect = 'http://www.website.com/page?id=23231';
$.redirectPost(redirect, {x: 'example', y: 'abc'});

// jquery extend function
$.extend(
{
    redirectPost: function(location, args)
    {
        var form = '';
        $.each( args, function( key, value ) {
            value = value.split('"').join('\"')
            form += '<input type="hidden" name="'+key+'" value="'+value+'">';
        });
        $('<form action="' + location + '" method="POST">' + form + '</form>').appendTo($(document.body)).submit();
    }
});
4
  • 1
    Note this will only work for data if it is one level deep like the example. For data such as {x: {z:'example'}, y: 'abc'} you'll have to JSON.stringify and then decode in your server side code.
    – Akhil F
    Commented Nov 25, 2014 at 15:39
  • @AakilFernandes where would be Json.stringify?
    – angel
    Commented Jan 6, 2016 at 18:39
  • @angel in modern browsers, there should be a global JSON object
    – Akhil F
    Commented Jan 20, 2016 at 16:56
  • Apparently this function requires "jquery.redirect.min.js plugin" Commented Jul 27, 2016 at 13:03
40

Here is a method, which does not use jQuery. I used it to create a bookmarklet, which checks the current page on w3-html-validator.

var f = document.createElement('form');
f.action='http://validator.w3.org/check';
f.method='POST';
f.target='_blank';

var i=document.createElement('input');
i.type='hidden';
i.name='fragment';
i.value='<!DOCTYPE html>'+document.documentElement.outerHTML;
f.appendChild(i);

document.body.appendChild(f);
f.submit();
0
38

If you are using jQuery, there is a redirect plugin that works with the POST or GET method. It creates a form with hidden inputs and submits it for you. An example of how to get it working:

$.redirect('demo.php', {'arg1': 'value1', 'arg2': 'value2'});

Note: You can pass the method types GET or POST as an optional third parameter; POST is the default.

3
  • This plugin worked great for me, thanks. I just copied and pasted the whole class into my code and use the example you have to test it and it worked fine. Now to include it properly...
    – OG Sean
    Commented Jul 9, 2018 at 0:12
  • Works like a charm. Thanks, @Tom. For those who wants to pass CSRF token with POST (I use Laravel framework) add it to the data like this: $.redirect('demo.php', {'arg1': 'value1', 'arg2': 'value2', '_token': '{{ csrf_token() }}'});. Have fun ;-)
    – Strabek
    Commented Mar 24, 2022 at 9:58
  • 1
    Worked great, just a copy and paste, thank you!
    – Doug Sisco
    Commented Jan 21, 2023 at 15:48
23

The answers here can be confusing so i will give you a sample code that i am working with.

To start with note that there is no POST parameter to java script windows.location function that you are referring to.

So you have to...

  1. Dynamically make a form with a POST parameter.

  2. Dynamically put a textbox or textboxes with your desired values to post

  3. Invoke the submit form you dynamically created.

And for the example.

     //---------- make sure to link to your jQuery library ----//

<script type="text/javascript" >

    var form = $(document.createElement('form'));
    $(form).attr("action", "test2.php");
    $(form).attr("method", "POST");
    $(form).css("display", "none");

    var input_employee_name = $("<input>")
    .attr("type", "text")
    .attr("name", "employee_name")
    .val("Peter" );
    $(form).append($(input_employee_name));


    var input_salary = $("<input>")
    .attr("type", "text")
    .attr("name", "salary")
    .val("1000" );
    $(form).append($(input_salary));

    form.appendTo( document.body );
    $(form).submit();

</script>

If all is done well, you shall be redirected to test2.php and you can use POST to read passed values of employee_name and salary; that will be Peter and 1000 respectively.

On test2.php you can get your values thus.

$employee_name = $_POST['employee_name'];
$salary = $_POST['salary'];

Needless to say , make sure you sanitize your passed values.

5
  • good answer. this will help some people Commented Feb 9, 2016 at 5:13
  • You are a superstar. Saved my entire day :) Commented Sep 22, 2017 at 10:13
  • hello, what i cannot understand is, since this is a post request, how would the target url loads its respective page?
    – vigamage
    Commented Jan 13, 2020 at 9:17
  • hey vigamage. when you do this the aim is not to display values in test2.php. Instead it is to procees the POST values. eg. Save employee name and salary onto a database.
    – webs
    Commented Jan 22, 2020 at 20:19
  • This to me was the cleanest solution. The property chaining (along with some indentation) helps a lot with readability (and maintainability). Thanks! Commented Apr 8, 2022 at 0:45
18

Generic function to post any JavaScript object to the given URL.

function postAndRedirect(url, postData)
{
    var postFormStr = "<form method='POST' action='" + url + "'>\n";

    for (var key in postData)
    {
        if (postData.hasOwnProperty(key))
        {
            postFormStr += "<input type='hidden' name='" + key + "' value='" + postData[key] + "'></input>";
        }
    }

    postFormStr += "</form>";

    var formElement = $(postFormStr);

    $('body').append(formElement);
    $(formElement).submit();
}
8

This is quite handy to use:

var myRedirect = function(redirectUrl, arg, value) {
  var form = $('<form action="' + redirectUrl + '" method="post">' +
  '<input type="hidden" name="'+ arg +'" value="' + value + '"></input>' + '</form>');
  $('body').append(form);
  $(form).submit();
};

then use it like:

myRedirect("/yourRedirectingUrl", "arg", "argValue");
1
var myRedirect = function(redirectUrl) {
var form = $('<form action="' + redirectUrl + '" method="post">' +
'<input type="hidden" name="parameter1" value="sample" />' +
'<input type="hidden" name="parameter2" value="Sample data 2" />' +
'</form>');
$('body').append(form);
$(form).submit();
};

Found code at http://www.prowebguru.com/2013/10/send-post-data-while-redirecting-with-jquery/

Going to try this and other suggestions for my work.

Is there any other way to do the same ?

0

You can use target attribute to send form with redirect from iframe. Your form open tag would be something like this:

method="post" action="http://some.url.com/form_action" target="_top"

Not the answer you're looking for? Browse other questions tagged or ask your own question.