JavaScript post request like a form submit

2018-12-30 23:06发布

I'm trying to direct a browser to a different page. If I wanted a GET request, I might say

document.location.href = 'http://example.com/q=a';

But the resource I'm trying to access won't respond properly unless I use a POST request. If this were not dynamically generated, I might use the HTML

<form action="http://example.com/" method="POST">
  <input type="hidden" name="q" value="a">
</form>

Then I would just submit the form from the DOM.

But really I would like JavaScript code that allows me to say

post_to_url('http://example.com/', {'q':'a'});

What's the best cross browser implementation?

Edit

I'm sorry I was not clear. I need a solution that changes the location of the browser, just like submitting a form. If this is possible with XMLHttpRequest, it is not obvious. And this should not be asynchronous, nor use XML, so Ajax is not the answer.

28条回答
与风俱净
2楼-- · 2018-12-30 23:44

Rakesh Pai's answer is amazing, but there is an issue that occurs for me (in Safari) when I try to post a form with a field called submit. For example, post_to_url("http://google.com/",{ submit: "submit" } );. I have patched the function slightly to walk around this variable space collision.

    function post_to_url(path, params, method) {
        method = method || "post";

        var form = document.createElement("form");

        //Move the submit function to another variable
        //so that it doesn't get overwritten.
        form._submit_function_ = form.submit;

        form.setAttribute("method", method);
        form.setAttribute("action", path);

        for(var key in params) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
        }

        document.body.appendChild(form);
        form._submit_function_(); //Call the renamed function.
    }
    post_to_url("http://google.com/", { submit: "submit" } ); //Works!
查看更多
路过你的时光
3楼-- · 2018-12-30 23:46

No, you cant have the JavaScript post request like a form submit.

What you can have is a form in HTML, then submit it with the JavaScript. (as explained many times on this page)

You can create the HTML yourself, you don't need JavaScript to write the HTML. That would be silly if people suggested that.

<form id="ninja" action="http://example.com/" method="POST">
  <input id="donaldduck" type="hidden" name="q" value="a">
</form>

Your function would just configure the form the way you want it.

function postToURL(a,b,c){
   document.getElementById("ninja").action     = a;
   document.getElementById("donaldduck").name  = b;
   document.getElementById("donaldduck").value = c;
   document.getElementById("ninja").submit();
}

Then, use it like.

postToURL("http://example.com/","q","a");

But I would just leave out the function and just do.

   document.getElementById('donaldduck').value = "a";
   document.getElementById("ninja").submit();

Finally, the style decision goes in the ccs file.

.ninja{ 
  display:none;
}

Personally I think forms should be addressed by name but that is not important right now.

查看更多
流年柔荑漫光年
4楼-- · 2018-12-30 23:47

This works perfectly in my case:

document.getElementById("form1").submit();

You can use it in function like:

function formSubmit() {
     document.getElementById("frmUserList").submit();
} 

Using this you can post all the values of inputs.

查看更多
裙下三千臣
5楼-- · 2018-12-30 23:47

My solution will encode deeply nested objects, unlike the currently accepted solution by @RakeshPai.

It uses the 'qs' npm library and its stringify function to convert nested objects into parameters.

This code works well with a Rails back-end, although you should be able to modify it to work with whatever backend you need by modifying the options passed to stringify. Rails requires that arrayFormat be set to "brackets".

import qs from "qs"

function normalPost(url, params) {
  var form = document.createElement("form");
  form.setAttribute("method", "POST");
  form.setAttribute("action", url);

  const keyValues = qs
    .stringify(params, { arrayFormat: "brackets", encode: false })
    .split("&")
    .map(field => field.split("="));

  keyValues.forEach(field => {
    var key = field[0];
    var value = field[1];
    var hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", key);
    hiddenField.setAttribute("value", value);
    form.appendChild(hiddenField);
  });
  document.body.appendChild(form);
  form.submit();
}

Example:

normalPost("/people/new", {
      people: [
        {
          name: "Chris",
          address: "My address",
          dogs: ["Jordan", "Elephant Man", "Chicken Face"],
          information: { age: 10, height: "3 meters" }
        },
        {
          name: "Andrew",
          address: "Underworld",
          dogs: ["Doug", "Elf", "Orange"]
        },
        {
          name: "Julian",
          address: "In a hole",
          dogs: ["Please", "Help"]
        }
      ]
    });

Produces these Rails parameters:

{"authenticity_token"=>"...",
 "people"=>
  [{"name"=>"Chris", "address"=>"My address", "dogs"=>["Jordan", "Elephant Man", "Chicken Face"], "information"=>{"age"=>"10", "height"=>"3 meters"}},
   {"name"=>"Andrew", "address"=>"Underworld", "dogs"=>["Doug", "Elf", "Orange"]},
   {"name"=>"Julian", "address"=>"In a hole", "dogs"=>["Please", "Help"]}]}
查看更多
ら面具成の殇う
6楼-- · 2018-12-30 23:50

You could dynamically add the form using DHTML and then submit.

查看更多
只靠听说
7楼-- · 2018-12-30 23:50

Here is how I do it.

function redirectWithPost(url, data){
        var form = document.createElement('form');
        form.method = 'POST';
        form.action = url;

        for(var key in data){
            var input = document.createElement('input');
            input.name = key;
            input.value = data[key];
            input.type = 'hidden';
            form.appendChild(input)
        }
        document.body.appendChild(form);
        form.submit();
    }
查看更多
登录 后发表回答