Frage JavaScript Post-Anfrage wie ein Formular absenden


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

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

Aber die Ressource, auf die ich zugreifen möchte, reagiert nicht richtig, wenn ich keine POST-Anfrage verwende. Wenn dies nicht dynamisch generiert würde, könnte ich den HTML-Code verwenden

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

Dann würde ich das Formular einfach vom DOM einreichen.

Aber wirklich möchte ich JavaScript-Code, der mir erlaubt zu sagen

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

Was ist die beste Cross-Browser-Implementierung?

Bearbeiten 

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


1277
2017-09-25 15:15


Ursprung


Antworten:


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

BEARBEITEN: Da dies so stark aufgewertet wurde, denke ich, dass die Leute das viel kopieren werden. Also habe ich das hinzugefügt hasOwnProperty Überprüfen Sie, ob Sie versehentlich Fehler behoben haben.


1841
2017-09-25 15:28



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

109
2018-04-04 00:21



Eine einfache und schnelle Implementierung von @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 z Prototyp oder jQuery...


62
2017-09-25 15:33



Verwendung der createElement Funktion bereitgestellt in diese Antwort, was notwendig ist wegen IEs Zerbrochenheit mit dem Namensattribut auf Elementen, die normalerweise mit erstellt werden document.createElement:

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
2017-09-25 15:29



Rakesh Pais Antwort ist erstaunlich, aber es gibt ein Problem, das für mich auftritt (in Safari) wenn ich versuche, ein Formular mit einem Feld namens submit. Beispielsweise, post_to_url("http://google.com/",{ submit: "submit" } );. Ich habe die Funktion leicht gepatcht, um diese Kollision mit dem variablen Raum 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!

34
2017-07-15 20:50



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

Was Sie haben können, ist ein Formular in HTML, dann senden Sie es mit dem JavaScript. (wie 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 albern, 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 nur die Form so konfigurieren, wie Sie es wollen.

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

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

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

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

Zum Schluss wird die Stilentscheidung in die ccs-Datei übernommen.

.ninja{ 
  display:none;
}

Persönlich denke ich, dass Formulare mit Namen adressiert werden sollten, aber das ist im Moment nicht wichtig.


27
2017-08-19 01:00



Wenn Sie haben Prototyp installiert, können Sie den Code zum Generieren und Senden des versteckten Formulars wie folgt straffen:

 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
2018-01-23 23:53



Dies ist die Antwort von Rakesh, aber mit Unterstützung für Arrays (was in Formularen ziemlich ü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, aber läuft 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(); 
}

18
2018-03-22 01:41



Nun, ich wünschte, ich hätte alle anderen Beiträge gelesen, also habe ich keine Zeit verloren, diese aus Rakesh Pais Antwort zu schaffen. Hier ist eine rekursive Lösung, die mit Arrays und Objekten funktioniert. Keine Abhängigkeit von jQuery.

Es wurde ein Segment hinzugefügt, um Fälle zu bearbeiten, in denen das gesamte Formular wie ein Array gesendet werden soll. (dh wo es kein Wrapper-Objekt um eine Liste von Elementen gibt)

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

16
2018-01-27 21:25



Eine Lösung besteht darin, das Formular zu generieren und zu senden. 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-Kürzel Bookmarklet mit einem einfachen implementieren

javascript:post_to_url('http://is.gd/create.php', {'URL': location.href});

15
2017-09-25 16:05



Drei Optionen hier.

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

  2. Stellen Sie die XMLHTTPRequest-Anforderung selbst und übergeben Sie die Post an die offene Methode statt an get. (Weitere Informationen 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 senden Sie sie ab.


11
2017-09-25 15:26