Question

J'essaie de diriger un navigateur vers une autre page. Si je voulais une demande GET, je pourrais dire

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

Mais la ressource à laquelle j'essaie d'accéder ne répondra pas correctement à moins d'utiliser une demande POST. Si cela n’était pas généré dynamiquement, je pourrais utiliser le code HTML

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

Ensuite, je soumettrais simplement le formulaire à partir du DOM.

Mais vraiment, j'aimerais un code JavaScript qui me permette de dire

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

Quelle est la meilleure implémentation multi-navigateurs?

Modifier

Je suis désolé de ne pas avoir été clair. J'ai besoin d'une solution qui modifie l'emplacement du navigateur, tout comme pour l'envoi d'un formulaire. Si cela est possible avec XMLHttpRequest , ce n'est pas évident. Et cela ne devrait pas être asynchrone, ni utiliser XML, donc Ajax n’est pas la solution.

Était-ce utile?

La solution

Créez dynamiquement <input> s dans un formulaire et envoyez-le

/**
 * 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='post') {

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

  for (const key in params) {
    if (params.hasOwnProperty(key)) {
      const hiddenField = document.createElement('input');
      hiddenField.type = 'hidden';
      hiddenField.name = key;
      hiddenField.value = params[key];

      form.appendChild(hiddenField);
    }
  }

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

Exemple:

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

MODIFIER : cette proposition ayant été tellement votée, j'imagine que les gens vont beaucoup copier-coller. J'ai donc ajouté la hasOwnProperty vérification pour corriger les bugs involontaires.

Autres conseils

Il s’agirait d’une version de la réponse sélectionnée utilisant 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();
}

Une implémentation simple et rapide de la réponse @Aaron:

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

Bien entendu, vous devriez plutôt utiliser un framework JavaScript tel que Prototype ou jQuery ...

Utilisation de la fonction createElement fournie dans cette réponse , ce qui est nécessaire en raison de La rupture de IE avec l'attribut name sur les éléments créés normalement avec 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);
}

La réponse de Rakesh Pai est étonnante, mais un problème se produit pour moi (dans Safari ) lorsque j'essaie de publier un formulaire avec un champ appelé submit. Par exemple, post_to_url("http://google.com/",{ submit: "submit" } );. J'ai légèrement modifié la fonction pour contourner cette collision spatiale variable.

    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!

Non. Vous ne pouvez pas recevoir la demande de publication JavaScript comme une soumission de formulaire.

Ce que vous pouvez avoir est un formulaire en HTML, puis soumettez-le avec JavaScript. (comme expliqué à plusieurs reprises sur cette page).

Vous pouvez créer le code HTML vous-même, vous n'avez pas besoin de JavaScript pour écrire le code HTML. Ce serait idiot si les gens le suggéraient.

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

Votre fonction configurerait simplement le formulaire comme vous le souhaitez.

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

Ensuite, utilisez-le comme.

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

Mais je voudrais juste laisser de côté la fonction et juste faire.

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

Enfin, la décision de style va dans le fichier ccs.

#ninja{ 
  display:none;
}

Personnellement, je pense que les formulaires doivent être nommés, mais ce n’est pas important pour le moment.

Si vous avez Prototype installé, vous pouvez renforcer le code pour générer et soumettre le formulaire masqué comme suit:

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

Telle est la réponse de rakesh, mais avec le support des tableaux (ce qui est assez courant dans les formulaires):

javascript simple:

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, et voici la version de jquery: (code légèrement différent, mais revient au même)

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

Une solution consiste à générer le formulaire et à le soumettre. Une implémentation est

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

Je peux donc mettre en place un bookmarklet de réduction d'URL avec un simple

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

Eh bien, j'aimerais avoir lu tous les autres articles pour ne pas perdre de temps à créer cela à partir de la réponse de Rakesh Pai. Voici une solution récursive qui fonctionne avec les tableaux et les objets. Aucune dépendance sur jQuery.

Ajout d'un segment pour gérer les cas où l'ensemble du formulaire doit être soumis comme un tableau. (c.-à-d. s'il n'y a pas d'objet wrapper autour d'une liste d'éléments)

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

Trois options ici.

  1. Réponse JavaScript standard: utilisez un cadre! La plupart des frameworks Ajax vous auront fourni un moyen simple de créer un XMLHTTPRequest POST.

  2. Faites la demande XMLHTTPRequest vous-même, en passant post dans la méthode open à la place de get. (Plus d'informations dans Utilisation de la méthode POST dans XMLHTTPRequest (Ajax) .)

  3. Via JavaScript, créez dynamiquement un formulaire, ajoutez une action, ajoutez vos entrées et soumettez-le.

Je descendrais la route de l'Ajax comme d'autres l'ont suggéré avec quelque chose comme:

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

Voici comment je l'ai écrit avec jQuery. Testé dans Firefox et Internet & Nbsp; 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();
}

La méthode la plus simple consiste à utiliser Ajax Post Request:

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

où:

  • data est un objet
  • dataType correspond aux données attendues par le serveur (xml, json, script, texte, html)
  • url est l'adresse de votre serveur RESt ou de toute fonction côté serveur acceptant HTTP-POST.

Ensuite, dans le gestionnaire de succès, redirigez le navigateur avec quelque chose comme window.location.

La bibliothèque Prototype comprend un objet Hashtable, avec " .toQueryString () " méthode, qui vous permet de transformer facilement un objet / une structure JavaScript en une chaîne de style de requête. Puisque la publication nécessite le & Quot; body & Quot; Si la requête est une chaîne formatée en chaîne de requête, cela permet à votre requête Ajax de fonctionner correctement en tant que publication. Voici un exemple utilisant 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();
};

Cela fonctionne parfaitement dans mon cas:

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

Vous pouvez l'utiliser dans des fonctions telles que:

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

En utilisant cela, vous pouvez publier toutes les valeurs des entrées.

FormObject est une option. Mais FormObject n'est plus supporté par la plupart des navigateurs.

Encore une autre solution récursive , certaines d’entre elles semblant en panne (je ne les ai pas toutes testées). Celui-ci dépend de lodash 3.x et de ES6 ( jQuery non requis):

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

Ma solution va coder des objets profondément imbriqués, contrairement à la solution actuellement acceptée par @RakeshPai.

Il utilise la bibliothèque npm 'qs' et sa fonction stringify pour convertir des objets imbriqués en paramètres.

Ce code fonctionne bien avec un back-end Rails, bien que vous devriez pouvoir le modifier pour fonctionner avec tout le back-end dont vous avez besoin en modifiant les options passées à stringify. Rails nécessite que arrayFormat soit défini sur & "; Accolades &";

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

Exemple:

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

Produit ces paramètres Rails:

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

Cela ressemble à l'option 2 d'Alan (ci-dessus). L’instanciation de httpobj est laissée sous la forme d’un exercice.

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

Ceci est basé sur le code de beauSD utilisant jQuery. Il est amélioré et fonctionne de manière récursive sur les objets.

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

Vous pouvez ajouter dynamiquement le formulaire à l'aide de DHTML, puis le soumettre.

Vous pouvez utiliser une bibliothèque telle que jQuery et sa méthode $ .post .

J'utilise le document.forms java et le boucle pour obtenir tous les éléments du formulaire, puis l'envoyer via xhttp. Voici donc ma solution pour javascript / ajax submit (avec tout le code HTML inclus à titre d'exemple):

          <!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>

La méthode que j'utilise pour envoyer et diriger automatiquement un utilisateur vers une autre page consiste à écrire un formulaire masqué, puis à le soumettre automatiquement. Soyez assuré que la forme masquée ne prend absolument aucun espace sur la page Web. Le code ressemblerait à ceci:

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

Application de l'envoi automatique

Une application de soumission automatique dirigerait les valeurs de formulaire que l'utilisateur inscrirait automatiquement sur l'autre page pour revenir à cette page. Une telle application serait comme ceci:

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

Voici comment je le fais.

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

plug-in jQuery pour la redirection avec POST ou GET:

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

Pour tester, incluez le fichier .js ci-dessus ou copiez / collez la classe dans votre code, puis utilisez le code ici, en remplaçant " args " avec vos noms de variables et " valeurs " avec les valeurs de ces variables respectives:

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

Vous pouvez utiliser la méthode de déclenchement jQuery pour soumettre le formulaire, comme si vous appuyiez sur un bouton,

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

il soumettra sur le navigateur.

Vous pouvez effectuer un appel AJAX (probablement à l'aide d'une bibliothèque telle que Prototype.js ou JQuery). AJAX peut gérer les options GET et POST.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top