it-swarm.com.de

JavaScript Post-Anfrage wie ein Formular absenden

Ich versuche, einen Browser auf eine andere Seite zu lenken. Wenn ich eine GET-Anfrage wollte, könnte ich sagen

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

Die Ressource, auf die ich zugreifen möchte, reagiert jedoch nicht richtig, wenn ich nicht eine POST Anforderung verwende. Wenn dies nicht dynamisch generiert würde, könnte ich HTML verwenden

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

Dann würde ich einfach das Formular aus dem DOM einreichen.

Aber ich möchte wirklich JavaScript-Code, mit dem ich sagen kann

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

Was ist die beste Browserübergreifende Implementierung?

Bearbeiten 

Es tut mir leid, dass ich nicht klar war. Ich brauche eine Lösung, die den Standort des Browsers ändert, genauso wie das Senden eines Formulars. Wenn dies mit XMLHttpRequest möglich ist, ist dies nicht offensichtlich. Dies sollte weder asynchron sein noch XML verwenden, daher ist Ajax nicht die Antwort.

1358
Joseph Holsten
 /**
 * sends a request to the specified url from a form. this will change the window location.
 * @param {string} path the path to send the post request to
 * @param {object} params the paramiters to add to the url
 * @param {string} [method=post] the method to use on the form
 */

function post(path, params, method) {
    method = method || "post"; // Set method to post by default if not specified.

    // The rest of this code assumes you are not using a library.
    // It can be made less wordy if you use one.
    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            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();
}

Beispiel:

post('/contact/', {name: 'Johnny Bravo'});

EDIT: Da dies so viel zugesagt hat, schätze ich, dass die Leute dies oft kopieren. Also fügte ich die hasOwnProperty-Prüfung hinzu, um unbeabsichtigte Fehler zu beheben.

1948
Rakesh Pai

Dies wäre eine Version der ausgewählten Antwort mit jQuery .

// Post to the provided URL with the specified parameters.
function post(path, parameters) {
    var form = $('<form></form>');

    form.attr("method", "post");
    form.attr("action", path);

    $.each(parameters, function(key, value) {
        var field = $('<input></input>');

        field.attr("type", "hidden");
        field.attr("name", key);
        field.attr("value", value);

        form.append(field);
    });

    // The form needs to be a part of the document in
    // order for us to be able to submit it.
    $(document.body).append(form);
    form.submit();
}
114
Ryan Delucchi

Eine einfache und schnelle Implementierung der @Aaron-Antwort:

document.body.innerHTML += '<form id="dynForm" action="http://example.com/" method="post"><input type="hidden" name="q" value="a"></form>';
document.getElementById("dynForm").submit();

Natürlich sollten Sie lieber ein JavaScript-Framework wie Prototype oder jQuery ... verwenden.

64

Verwenden der createElement-Funktion, die in this answer zur Verfügung gestellt wird, was aufgrund der Brokenness von IE mit dem Namensattribut für Elemente erforderlich ist, die normalerweise mit document.createElement erstellt wurden:

function postToURL(url, values) {
    values = values || {};

    var form = createElement("form", {action: url,
                                      method: "POST",
                                      style: "display: none"});
    for (var property in values) {
        if (values.hasOwnProperty(property)) {
            var value = values[property];
            if (value instanceof Array) {
                for (var i = 0, l = value.length; i < l; i++) {
                    form.appendChild(createElement("input", {type: "hidden",
                                                             name: property,
                                                             value: value[i]}));
                }
            }
            else {
                form.appendChild(createElement("input", {type: "hidden",
                                                         name: property,
                                                         value: value}));
            }
        }
    }
    document.body.appendChild(form);
    form.submit();
    document.body.removeChild(form);
}
51
Jonny Buchanan

Rakesh Pais Antwort ist erstaunlich, aber es gibt ein Problem, das für mich (in Safari ) auftritt, wenn ich versuche, ein Formular mit einem Feld namens submit zu posten. Zum Beispiel post_to_url("http://google.com/",{ submit: "submit" } );. Ich habe die Funktion etwas gepatcht, um diese variable Weltraumkollision zu umgehen.

    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!
35
Kendall Hopkins

Nein, Sie können die JavaScript-Post-Anfrage nicht wie ein Formular einreichen.

Was Sie haben können, ist ein Formular in HTML, dann senden Sie es mit dem JavaScript. (wie schon oft auf dieser Seite erklärt)

Sie können den HTML-Code selbst erstellen, Sie benötigen kein JavaScript, um den HTML-Code zu schreiben. Das wäre dumm, wenn die Leute das vorschlagen würden.

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

Ihre Funktion würde das Formular einfach so konfigurieren, wie Sie es möchten.

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

Dann benutze es gerne.

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

Aber ich würde die Funktion einfach weglassen und einfach tun.

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

Die Stilentscheidung wird schließlich in der ccs-Datei gespeichert.

.ninja{ 
  display:none;
}

Ich persönlich denke, dass Formulare mit Namen angesprochen werden sollten, aber das ist im Moment nicht wichtig.

27
gaby de wilde

Wenn Sie Prototype installiert haben, können Sie den Code straffen, um das verborgene Formular zu generieren und zu senden:

 var form = new Element('form',
                        {method: 'post', action: 'http://example.com/'});
 form.insert(new Element('input',
                         {name: 'q', value: 'a', type: 'hidden'}));
 $(document.body).insert(form);
 form.submit();
24
Head

dies ist die Antwort von Rakesh, aber mit Unterstützung für Arrays (was in Formularen durchaus üblich ist): 

einfaches Javascript: 

function post_to_url(path, params, method) {
    method = method || "post"; // Set method to post by default, if not specified.

    // The rest of this code assumes you are not using a library.
    // It can be made less wordy if you use one.
    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    var addField = function( key, value ){
        var hiddenField = document.createElement("input");
        hiddenField.setAttribute("type", "hidden");
        hiddenField.setAttribute("name", key);
        hiddenField.setAttribute("value", value );

        form.appendChild(hiddenField);
    }; 

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            if( params[key] instanceof Array ){
                for(var i = 0; i < params[key].length; i++){
                    addField( key, params[key][i] )
                }
            }
            else{
                addField( key, params[key] ); 
            }
        }
    }

    document.body.appendChild(form);
    form.submit();
}

oh, und hier ist die Jquery-Version: (etwas anderer Code, läuft aber auf dasselbe hinaus)

function post_to_url(path, params, method) {
    method = method || "post"; // Set method to post by default, if not specified.

    var form = $(document.createElement( "form" ))
        .attr( {"method": method, "action": path} );

    $.each( params, function(key,value){
        $.each( value instanceof Array? value : [value], function(i,val){
            $(document.createElement("input"))
                .attr({ "type": "hidden", "name": key, "value": val })
                .appendTo( form );
        }); 
    } ); 

    form.appendTo( document.body ).submit(); 
}
21
kritzikratzi

Nun, ich wünschte, ich hätte alle anderen Beiträge gelesen, damit ich keine Zeit verliere, indem ich die Antwort von Rakesh Pai erstellte. Hier ist eine rekursive Lösung, die mit Arrays und Objekten arbeitet. Keine Abhängigkeit von jQuery.

Es wurde ein Segment hinzugefügt, um Fälle zu behandeln, bei denen das gesamte Formular wie ein Array übermittelt werden soll. (dh wo kein Wrapper-Objekt um eine Liste von Elementen ist)

/**
 * Posts javascript data to a url using form.submit().  
 * Note: Handles json and arrays.
 * @param {string} path - url where the data should be sent.
 * @param {string} data - data as javascript object (JSON).
 * @param {object} options -- optional attributes
 *  { 
 *    {string} method: get/post/put/etc,
 *    {string} arrayName: name to post arraylike data.  Only necessary when root data object is an array.
 *  }
 * @example postToUrl('/UpdateUser', {Order {Id: 1, FirstName: 'Sally'}});
 */
function postToUrl(path, data, options) {
    if (options === undefined) {
        options = {};
    }

    var method = options.method || "post"; // Set method to post by default if not specified.

    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    function constructElements(item, parentString) {
        for (var key in item) {
            if (item.hasOwnProperty(key) && item[key] != null) {
                if (Object.prototype.toString.call(item[key]) === '[object Array]') {
                    for (var i = 0; i < item[key].length; i++) {
                        constructElements(item[key][i], parentString + key + "[" + i + "].");
                    }
                } else if (Object.prototype.toString.call(item[key]) === '[object Object]') {
                    constructElements(item[key], parentString + key + ".");
                } else {
                    var hiddenField = document.createElement("input");
                    hiddenField.setAttribute("type", "hidden");
                    hiddenField.setAttribute("name", parentString + key);
                    hiddenField.setAttribute("value", item[key]);
                    form.appendChild(hiddenField);
                }
            }
        }
    }

    //if the parent 'data' object is an array we need to treat it a little differently
    if (Object.prototype.toString.call(data) === '[object Array]') {
        if (options.arrayName === undefined) console.warn("Posting array-type to url will doubtfully work without an arrayName defined in options.");
        //loop through each array item at the parent level
        for (var i = 0; i < data.length; i++) {
            constructElements(data[i], (options.arrayName || "") + "[" + i + "].");
        }
    } else {
        //otherwise treat it normally
        constructElements(data, "");
    }

    document.body.appendChild(form);
    form.submit();
};
15
emragins

Eine Lösung besteht darin, das Formular zu generieren und abzusenden. Eine Implementierung ist

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

    for (var i in params) {
        if (params.hasOwnProperty(i)) {
            var input = document.createElement('input');
            input.type = 'hidden';
            input.name = i;
            input.value = params[i];
            form.appendChild(input);
        }
    }

    form.submit();
}

So kann ich ein URL-verkürzendes Bookmarklet mit einem einfachen implementieren

javascript:post_to_url('http://is.Gd/create.php', {'URL': location.href});
14
Joseph Holsten

Drei Möglichkeiten hier.

  1. Standard JavaScript Antwort: Verwenden Sie ein Framework! Die meisten Ajax-Frameworks haben Ihnen eine einfache Möglichkeit geboten, einen XMLHTTPRequest POST zu erstellen.

  2. Stellen Sie die XMLHTTPRequest-Anforderung selbst her, und übergeben Sie die Post an die open-Methode, anstatt sie zu erhalten. (Weitere Informationen finden Sie in Verwenden der POST - Methode in XMLHTTPRequest (Ajax).)

  3. Erstellen Sie über JavaScript dynamisch ein Formular, fügen Sie eine Aktion hinzu, fügen Sie Ihre Eingaben hinzu und übergeben Sie diese.

11
Alan Storm

So habe ich es mit jQuery geschrieben. Getestet in Firefox und Internet Explorer.

function postToUrl(url, params, newWindow) {
    var form = $('<form>');
    form.attr('action', url);
    form.attr('method', 'POST');
    if(newWindow){ form.attr('target', '_blank'); 
  }

  var addParam = function(paramName, paramValue) {
      var input = $('<input type="hidden">');
      input.attr({ 'id':     paramName,
                 'name':   paramName,
                 'value':  paramValue });
      form.append(input);
    };

    // Params is an Array.
    if(params instanceof Array){
        for(var i=0; i<params.length; i++) {
            addParam(i, params[i]);
        }
    }

    // Params is an Associative array or Object.
    if(params instanceof Object) {
        for(var key in params){
            addParam(key, params[key]);
        }
    }

    // Submit the form, then remove it from the page
    form.appendTo(document.body);
    form.submit();
    form.remove();
}
10
beauburrier

Ich würde die Ajax-Route hinuntergehen, wie andere vorgeschlagen haben:

var xmlHttpReq = false;

var self = this;
// Mozilla/Safari
if (window.XMLHttpRequest) {
    self.xmlHttpReq = new XMLHttpRequest();
}
// IE
else if (window.ActiveXObject) {
    self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}

self.xmlHttpReq.open("POST", "YourPageHere.asp", true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');

self.xmlHttpReq.setRequestHeader("Content-length", QueryString.length);



self.xmlHttpReq.send("?YourQueryString=Value");
9
Katy

Der einfachste Weg ist die Verwendung von Ajax Post Request:

$.ajax({
    type: "POST",
    url: 'http://www.myrestserver.com/api',
    data: data,
    success: success,
    dataType: dataType
    });

woher:

  • daten sind ein Objekt
  • dataType sind die vom Server erwarteten Daten (xml, json, Skript, Text, HTML) 
  • uRL ist die Adresse Ihres RESt-Servers oder einer Funktion auf der Serverseite, die den HTTP-POST akzeptiert.

Dann leiten Sie im Erfolgs-Handler den Browser mit etwas wie window.location um.

6
JLavoie

Die Prototype - Bibliothek enthält ein Hashtable-Objekt mit der Methode ".toQueryString ()", mit der Sie ein JavaScript-Objekt/eine JavaScript-Struktur leicht in eine Abfragezeichenfolge-Zeichenfolge umwandeln können. Da der Beitrag erfordert, dass der "Hauptteil" der Anforderung eine aus einer Abfragezeichenfolge formatierte Zeichenfolge ist, kann Ihre Ajax-Anforderung als Beitrag ordnungsgemäß funktionieren. Hier ist ein Beispiel mit Prototype:

$req = new Ajax.Request("http://foo.com/bar.php",{
    method: 'post',
    parameters: $H({
        name: 'Diodeus',
        question: 'JavaScript posts a request like a form request',
        ...
    }).toQueryString();
};
5
Adam Ness

Das funktioniert in meinem Fall perfekt:

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

Sie können es in der Funktion wie verwenden:

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

Damit können Sie alle Werte der Eingaben buchen.

3
ChintanThummar

Im Gegensatz zu der derzeit von @RakeshPai akzeptierten Lösung wird meine Lösung tief verschachtelte Objekte kodieren.

Es verwendet die 'qs' npm-Bibliothek und ihre Funktion stringify, um verschachtelte Objekte in Parameter zu konvertieren.

Dieser Code funktioniert gut mit einem Rails-Backend, obwohl Sie in der Lage sein sollten, ihn mit dem von Ihnen benötigten Backend zu modifizieren, indem Sie die Optionen ändern, die an stringify übergeben werden. Rails erfordert, dass arrayFormat auf "Klammern" gesetzt ist.

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

Beispiel:

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"]
        }
      ]
    });

Produziert diese Rails-Parameter:

{"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"]}]}
2
cmrichards

Noch eine andere rekursive Lösung, da einige andere als defekt erscheinen (ich habe nicht alle getestet). Diese hängt von lodash 3.x und ES6 ab (jQuery nicht erforderlich):

function createHiddenInput(name, value) {
    let input = document.createElement('input');
    input.setAttribute('type','hidden');
    input.setAttribute('name',name);
    input.setAttribute('value',value);
    return input;
}

function appendInput(form, name, value) {
    if(_.isArray(value)) {
        _.each(value, (v,i) => {
            appendInput(form, `${name}[${i}]`, v);
        });
    } else if(_.isObject(value)) {
        _.forOwn(value, (v,p) => {
            appendInput(form, `${name}[${p}]`, v);
        });
    } else {
        form.appendChild(createHiddenInput(name, value));
    }
}

function postToUrl(url, data) {
    let form = document.createElement('form');
    form.setAttribute('method', 'post');
    form.setAttribute('action', url);

    _.forOwn(data, (value, name) => {
        appendInput(form, name, value);
    });

    form.submit();
}
2
mpen

Sie können das Formular mithilfe von DHTML dynamisch hinzufügen und anschließend senden.

1
AnthonyWJones

Sie könnten eine Bibliothek wie jQuery und ihre $ .post-Methode verwenden.

1
Bill Turner

Ich verwende die document.forms Java und verwende eine Schleife, um alle Elemente im Formular zu erhalten, und sende dann über xhttp. Das ist also meine Lösung für Javascript/Ajax-Submit (mit allen HTML-Dateien als Beispiel):

          <!DOCTYPE html>
           <html>
           <body>
           <form>
       First name: <input type="text" name="fname" value="Donald"><br>
        Last name: <input type="text" name="lname" value="Duck"><br>
          Addr1: <input type="text" name="add" value="123 Pond Dr"><br>
           City: <input type="text" name="city" value="Duckopolis"><br>
      </form> 



           <button onclick="smc()">Submit</button>

                   <script>
             function smc() {
                  var http = new XMLHttpRequest();
                       var url = "yourphpfile.php";
                     var x = document.forms[0];
                          var xstr = "";
                         var ta ="";
                    var tb ="";
                var i;
               for (i = 0; i < x.length; i++) {
     if (i==0){ta = x.elements[i].name+"="+ x.elements[i].value;}else{
       tb = tb+"&"+ x.elements[i].name +"=" + x.elements[i].value;
             } }

           xstr = ta+tb;
      http.open("POST", url, true);
       http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

      http.onreadystatechange = function() {
          if(http.readyState == 4 && http.status == 200) {

        // do whatever you want to with the html output response here

                } 

               }
            http.send(xstr);

              }
         </script>

         </body>
     </html>
1
drtechno

Dies basiert auf dem Code von beauSD, der jQuery verwendet. Es wurde verbessert, sodass es bei Objekten rekursiv funktioniert.

function post(url, params, urlEncoded, newWindow) {
    var form = $('<form />').hide();
    form.attr('action', url)
        .attr('method', 'POST')
        .attr('enctype', urlEncoded ? 'application/x-www-form-urlencoded' : 'multipart/form-data');
    if(newWindow) form.attr('target', '_blank');

    function addParam(name, value, parent) {
        var fullname = (parent.length > 0 ? (parent + '[' + name + ']') : name);
        if(value instanceof Object) {
            for(var i in value) {
                addParam(i, value[i], fullname);
            }
        }
        else $('<input type="hidden" />').attr({name: fullname, value: value}).appendTo(form);
    };

    addParam('', params, '');

    $('body').append(form);
    form.submit();
}
1
bobef

Dies ist wie bei Option 2 von Alan (oben). Wie man das httpobj instanziiert, bleibt als Übung übrig.

httpobj.open("POST", url, true);
httpobj.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
httpobj.onreadystatechange=handler;
httpobj.send(post);
1
R. Van Hoose

FormObject ist eine Option. FormObject wird derzeit jedoch von den meisten Browsern nicht unterstützt.

1
lingceng

Die Methode, mit der ich einen Benutzer automatisch poste und auf eine andere Seite weiterleitet, besteht darin, einfach ein verstecktes Formular zu schreiben und es dann automatisch zu senden. Seien Sie versichert, dass das versteckte Formular auf der Webseite absolut keinen Platz einnimmt. Der Code würde ungefähr so ​​aussehen:

    <form name="form1" method="post" action="somepage.php">
    <input name="fielda" type="text" id="fielda" type="hidden">

    <textarea name="fieldb" id="fieldb" cols="" rows="" style="display:none"></textarea>
</form>
    document.getElementById('fielda').value="some text for field a";
    document.getElementById('fieldb').innerHTML="some text for multiline fieldb";
    form1.submit();

Anwendung von Auto Submit

Eine Anwendung der automatischen Übermittlung würde Formularwerte, die der Benutzer automatisch auf der anderen Seite eingibt, auf diese Seite umleiten. Eine solche Anwendung wäre so:

fieldapost=<?php echo $_post['fielda'];>
if (fieldapost !="") {
document.write("<form name='form1' method='post' action='previouspage.php'>
  <input name='fielda' type='text' id='fielda' type='hidden'>
</form>");
document.getElementById('fielda').value=fieldapost;
form1.submit();
}
0
rauprog

So mache ich es.

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();
    }
0
nikksan

jQuery-Plugin zur Weiterleitung mit POST oder GET:

https://github.com/mgalante/jquery.redirect/blob/master/jquery.redirect.js

Um dies zu testen, schließen Sie die obige .js-Datei ein oder kopieren/fügen Sie die Klasse in Ihren Code ein. Verwenden Sie dann den Code hier und ersetzen Sie "args" durch Ihre Variablennamen und "values" durch die Werte dieser Variablen:

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

Sie könnten die jQuery-Triggermethode zum Senden des Formulars verwenden, genau wie Sie eine Schaltfläche drücken.

$('form').trigger('submit')

es wird im Browser eingereicht.

0
Canaan Etai