Prośba o przesłanie kodu JavaScript jak formularz

1530

Próbuję skierować przeglądarkę na inną stronę. Gdybym chciał żądania GET, mógłbym powiedzieć

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

Ale zasób, do którego próbuję uzyskać dostęp, nie zareaguje poprawnie, chyba że użyję żądania POST. Jeśli nie byłyby generowane dynamicznie, mógłbym użyć HTML

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

Następnie prześlę formularz z DOM.

Ale naprawdę chciałbym kodu JavaScript, który pozwala mi powiedzieć

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

Jaka jest najlepsza implementacja w różnych przeglądarkach?

Edytować

Przepraszam, że nie było jasne. Potrzebuję rozwiązania, które zmienia lokalizację przeglądarki, podobnie jak przesłanie formularza. Jeśli jest to możliwe w przypadku XMLHttpRequest , nie jest to oczywiste. I to nie powinno być asynchroniczne ani używać XML, więc Ajax nie jest odpowiedzią.

Joseph Holsten
źródło
1
Jak wspomniano w innym wątku, istnieje wtyczka „.redirect” jquery, która działa z metodą POST lub GET. Tworzy formularz z ukrytymi danymi wejściowymi i przesyła go za Ciebie. Np .: $ .redirect („demo.php”, {„arg1”: „wartość1”, „arg2”: „wartość2”}); github.com/mgalante/jquery.redirect/blob/master/…
OG Sean

Odpowiedzi:

2144

Dynamicznie twórz <input>s w formularzu i prześlij go

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

Przykład:

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

EDYCJA : Odkąd to zostało tak wysoko ocenione, domyślam się, że ludzie będą to często kopiować. Dodałem więc hasOwnPropertyczek, aby naprawić wszelkie niezamierzone błędy.

Rakesh Pai
źródło
10
Co z tablicami w paramach danych? Jquery post () interpretuje np .: „data: {array: [1, 2, 3]}” jako? Array = 1 i array = 2 & array = 3. Ten kod daje kolejny wynik.
Scit
18
Ostrzeżenie: Pomimo wielu pozytywnych opinii, to rozwiązanie jest ograniczone i nie obsługuje tablic ani zagnieżdżonych obiektów w formularzu. W przeciwnym razie jest to świetna odpowiedź.
emragins
3
niesamowite, że nie jest to natywnie obsługiwane przez HTML ani javascript, a nie jquery. Musisz to zakodować.
eugene
14
@mricci Celem tego fragmentu jest przekierowanie przeglądarki do nowego adresu URL określonego przez akcję; jeśli pozostajesz na tej samej stronie, możesz po prostu użyć tradycyjnego AJAX do wysłania swoich danych. Ponieważ przeglądarka powinna przechodzić do nowej strony, zawartość DOM bieżącej strony nie będzie miała znaczenia
Ken Bellows
6
Użytkownicy Python, Django i prawdopodobnie Flask zobaczą następujący błąd: „Zabronione (403). Weryfikacja CSRF nie powiodła się. Żądanie przerwane.”, Jeśli tworzysz formularz od zera. W takim przypadku musisz przekazać token csrf w ten sposób: post ('/ contact /', {name: 'Johnny Bravo', csrfmiddlewaretoken: $ ("# csrf_token"). Val ()});
Davidson Lima,
129

To byłaby wersja wybranej odpowiedzi przy użyciu 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();
}
Ryan Delucchi
źródło
2
Naprawiono: teraz
dołącza się
7
Lekko zmodyfikowano to, aby obsługiwać tablice i obiekty gist.github.com/hom3chuk/692bf12fe7dac2486212
НЛО
3
Jeśli wartość zawiera znak xml dangeours, nie zadziała to w ASP.NET encodeUriComponent (wartość) jest wymagany. Następnie kod UrlDecode jest również wymagany po stronie serwera.
Stefan Steiger,
Jeśli twoje potrzeby są proste, ta funkcja jest niepotrzebna. Ten $("<form method='POST' action='https://example.com'><input type='hidden' name='q' value='a'/></form>").appendTo("body").submit();
jednowarstwowy
71

Prosta szybka i brudna implementacja odpowiedzi @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();

Oczywiście powinieneś raczej użyć frameworka JavaScript, takiego jak Prototype lub jQuery ...

Alexandre Victoor
źródło
6
Czy można to zrobić bez ładowania strony internetowej w bieżącym oknie / karcie przeglądarki?
pbreitenbach
54

Korzystanie z createElementfunkcji podanej w tej odpowiedzi , która jest konieczna ze względu na zerwanie IE z atrybutem name na elementach tworzonych normalnie za pomocą 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);
}
Jonny Buchanan
źródło
6
Czy musisz usunąć dziecko po złożeniu? Czy i tak strona nie zniknie?
Nils
2
Nie ma sensu usuwać dziecka po przesłaniu, z wyjątkiem sytuacji, gdy używana jest sesja i te dane są zapisywane.
Miloš
6
@CantucciHQ Strona może równie dobrze pozostać niezmieniona, nawet jeśli nie jest ustawiony cel formularza. Na przykład jest 204 Brak treści .
Eugene Ryabtsev
38

Odpowiedź Rakesha Pai jest niesamowita, ale pojawia się problem (w Safari ), gdy próbuję wysłać formularz z polem o nazwie submit. Na przykład post_to_url("http://google.com/",{ submit: "submit" } );. Lekko załatałem tę funkcję, aby obejść to zderzenie zmiennej przestrzeni.

    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!
Kendall Hopkins
źródło
7
2018 i wciąż nie lepsza odpowiedź?
iiirxs
30

Nie. Nie możesz poprosić o przesłanie posta JavaScript jak formularz.

Możesz mieć formularz w HTML, a następnie przesłać go za pomocą JavaScript. (jak wyjaśniono wiele razy na tej stronie).

Możesz sam stworzyć HTML, nie potrzebujesz JavaScript do pisania HTML. Byłoby głupie, gdyby ludzie to sugerowali.

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

Twoja funkcja po prostu skonfiguruje formularz tak, jak chcesz.

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

Następnie użyj go jak.

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

Ale po prostu pominę tę funkcję i po prostu zrobię.

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

Wreszcie decyzja o stylu przechodzi do pliku ccs.

#ninja{ 
  display:none;
}

Osobiście uważam, że formularze powinny być adresowane po imieniu, ale w tej chwili nie jest to ważne.

gaby de wilde
źródło
26

Jeśli masz zainstalowany Prototyp , możesz zaostrzyć kod, aby wygenerować i przesłać ukryty formularz w następujący sposób:

 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();
Głowa
źródło
25

oto odpowiedź rakesh, ale z obsługą tablic (co jest dość powszechne w formach):

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

och, a oto wersja jquery: (nieco inny kod, ale sprowadza się do tego samego)

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(); 
}
kritzikratzi
źródło
3
ps lubię teraz korzystać z tej funkcji, ale zamiast przesyłać formularz na końcu, po prostu zwracam go z powrotem do osoby dzwoniącej. w ten sposób mogę łatwo ustawić dodatkowe atrybuty lub w razie potrzeby wykonać inne czynności.
kritzikratzi
3
Świetny! bardzo przydatne. Mała zmiana dla osób, które polegają na PHP po stronie serwera tego formularza, zmieniłem addField (klucz, parametry [klucz] [i]) na addField (klucz + „[]”, parametry [klucz] [i]). To sprawia, że ​​$ _POST [klucz] jest dostępny jako tablica.
Thava,
2
@Thava możesz również ustawić name = "bla []" w swoim polu wejściowym. tak czy inaczej, istnieją języki inne niż php, które nie obsługują składni [], więc zostawiam to bez zmian.
kritzikratzi,
17

Jednym z rozwiązań jest wygenerowanie formularza i przesłanie go. Jedna implementacja to

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

Mogę więc zaimplementować bookmarklet skracający adresy URL za pomocą prostej

javascript:post_to_url('http://is.gd/create.php', {'URL': location.href});
Joseph Holsten
źródło
16

Cóż, chciałbym przeczytać wszystkie pozostałe posty, aby nie tracić czasu na tworzenie tego z odpowiedzi Rakesh Pai. Oto rekurencyjne rozwiązanie, które działa z tablicami i obiektami. Brak zależności od jQuery.

Dodano segment do obsługi przypadków, w których cały formularz należy przesłać jak tablicę. (tzn. gdzie wokół listy przedmiotów nie ma obiektu opakowującego)

/**
 * 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();
};
emragins
źródło
1
To również nie wydaje się poprawnie kodować zagnieżdżonych obiektów.
mpen
1
@mpen masz skrzypce?
emragins
1
Nie przepraszam Łatwo było napisać siebie; nie warto czasu debugować.
mpen
12

Tutaj trzy opcje.

  1. Standardowa odpowiedź JavaScript: użyj frameworka! Większość frameworków Ajax wyodrębni cię z łatwego sposobu na wykonanie testu POST XMLHTTPRequest .

  2. Złóż zapytanie XMLHTTPRequest samodzielnie, przekazując pocztę do metody otwartej zamiast get. (Więcej informacji w temacie Korzystanie z metody POST w XMLHTTPRequest (Ajax) .)

  3. Za pomocą JavaScript dynamicznie utwórz formularz, dodaj akcję, dodaj dane wejściowe i prześlij ją.

Alan Storm
źródło
5
XMLHTTPRequest nie aktualizuje okna. Próbujesz powiedzieć, że powinienem skończyć z AJAX dokumentem.write (http.responseText)?
Joseph Holsten
11
Dlaczego należy dodać 30k + do jego projektu, jeśli nie robi on nic więcej z frameworkiem?
Dementyczny
12

Wybrałbym trasę Ajax, jak sugerowali inni, z czymś takim jak:

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");
Katy
źródło
1
Uncaught ReferenceError: QueryString nie jest zdefiniowany.
Chase Roberts,
11

Najłatwiejszym sposobem jest użycie Ajax Post Request:

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

gdzie:

  • dane są przedmiotem
  • dataType to dane oczekiwane przez serwer (xml, json, skrypt, tekst, html)
  • url to adres twojego serwera RESt lub dowolnej funkcji po stronie serwera, która akceptuje HTTP-POST.

Następnie w module obsługi sukcesu przekieruj przeglądarkę za pomocą czegoś takiego jak window.location.

JLavoie
źródło
5
Nie wspominałeś, że oferowane przez ciebie podejście opiera się na bibliotece JavaScript jQuery .
DavidRR
8
nie trafiłeś także w sedno pytania - chce „przekierować przeglądarkę na inną stronę”, a nie wysyłać żądania ajax.
Czarny
Możesz poczekać na odpowiedź, a następnie document.location = {url}; Mogę sobie tylko wyobrazić, że to nie zadziała, jeśli przekierujesz do pliku do pobrania.
Epirocks
11

Oto jak napisałem to za pomocą jQuery. Testowane w Firefox i 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();
}
beauburrier
źródło
1
Pracował dla mnie. Dzięki. (Testowane w Chrome)
dannie.f
2
Myślę, że problem może polegać na tym, że formularz zostanie usunięty przed powrotem zgłoszenia. Słyszałem, że w niektórych przeglądarkach przeniesienie lub usunięcie formularza przed zakończeniem wysyłania spowoduje, że programy obsługi nie będą uruchamiane. Zamiast tego usuń formularz z dokumentu w module obsługi.
Jeff DQ
Działa jak marzenie. Testowane na Firefox + Chrome + IE11 - dziękuję bardzo za to!
Deunz
6

Prototype biblioteka zawiera Hashtable obiekt, z „.toQueryString ()” metoda, która pozwala łatwo włączyć JavaScript Object / struktury na ciąg znaków zapytania w stylu string. Ponieważ post wymaga, aby „treść” żądania była ciągiem sformatowanym jako ciąg zapytania, umożliwia to poprawne działanie żądania Ajax jako posta. Oto przykład z użyciem Prototypu:

$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();
};
Adam Ness
źródło
1
To jedno z niewielu rozwiązań, które nie zastępuje aktualnie wyświetlanego dokumentu zwrotem odpowiedzi serwera.
dothebart
4

Działa to doskonale w moim przypadku:

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

Możesz użyć go w funkcji takiej jak:

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

Za pomocą tego możesz opublikować wszystkie wartości danych wejściowych.

Chintan Thummar
źródło
3

Jeszcze jedno rekurencyjne rozwiązanie, ponieważ niektóre z nich wydają się być zepsute (nie przetestowałem ich wszystkich). To zależy od lodash 3.x i ES6 (jQuery nie jest wymagane):

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();
}
mpen
źródło
3

Moje rozwiązanie koduje głęboko zagnieżdżone obiekty, w przeciwieństwie do obecnie akceptowanego rozwiązania @RakeshPai.

Wykorzystuje bibliotekę npm „qs” i jej funkcję stringify do przekształcania zagnieżdżonych obiektów w parametry.

Ten kod działa dobrze z back-endem Railsów, chociaż powinieneś być w stanie zmodyfikować go, aby działał z dowolnym backendem, którego potrzebujesz, modyfikując opcje przekazane do stringify. Railsy wymagają, aby tablicaFormat była ustawiona na „nawiasy”.

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

Przykład:

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

Tworzy następujące parametry Railsów:

{"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"]}]}
cmrichards
źródło
2

FormObject jest opcją. Ale FormObject nie jest obecnie obsługiwany przez większość przeglądarek.

lingceng
źródło
1

To jest jak opcja Alana 2 (powyżej). Jak utworzyć instancję httpobj, pozostawia się jako ćwiczenie.

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

Jest to oparte na kodzie beauSD używającym jQuery. Jest ulepszony, dzięki czemu działa rekurencyjnie na obiektach.

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();
}
Bobf
źródło
1

Możesz dynamicznie dodać formularz za pomocą DHTML, a następnie przesłać.

AnthonyWJones
źródło
1

Możesz użyć biblioteki takiej jak jQuery i jej metody $ .post .

Bill Turner
źródło
2
Pamiętaj, że $ .post to tylko AJAX.
Bryan Larsen
1

Używam java document.forms i zapętlam go, aby uzyskać wszystkie elementy w formularzu, a następnie wysyłam za pośrednictwem xhttp. To jest moje rozwiązanie dla przesyłania javascript / ajax (z całym kodem HTML zawartym jako przykład):

          <!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>
drtechno
źródło
1

Możesz użyć metody wyzwalacza jQuery do przesłania formularza, tak jak naciskasz przycisk, tak jak,

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

prześle w przeglądarce.

Canaan Etai
źródło
0

Metodą, której używam do automatycznego wysyłania i kierowania użytkownika na inną stronę, jest napisanie ukrytego formularza, a następnie automatyczne przesłanie go. Zapewniamy, że ukryta forma absolutnie nie zajmuje miejsca na stronie internetowej. Kod byłby mniej więcej taki:

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

Zastosowanie automatycznego przesyłania

Zastosowanie automatycznego wysyłania kierowałoby wartości formularza, które użytkownik automatycznie umieszczał na drugiej stronie z powrotem na tę stronę. Taka aplikacja wyglądałaby tak:

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();
}
rauprog
źródło
0

Oto jak to robię.

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();
    }
nikksan
źródło
0

Żadne z powyższych rozwiązań nie obsługiwało głęboko zagnieżdżonych parametrów za pomocą jQuery, więc oto moje rozwiązanie za dwa centy.

Jeśli używasz jQuery i potrzebujesz obsługi głęboko zagnieżdżonych parametrów, możesz użyć tej funkcji poniżej:

    /**
     * Original code found here: https://github.com/mgalante/jquery.redirect/blob/master/jquery.redirect.js
     * I just simplified it for my own taste.
     */
    function postForm(parameters, url) {

        // generally we post the form with a blank action attribute
        if ('undefined' === typeof url) {
            url = '';
        }


        //----------------------------------------
        // SOME HELPER FUNCTIONS
        //----------------------------------------
        var getForm = function (url, values) {

            values = removeNulls(values);

            var form = $('<form>')
                .attr("method", 'POST')
                .attr("action", url);

            iterateValues(values, [], form, null);
            return form;
        };

        var removeNulls = function (values) {
            var propNames = Object.getOwnPropertyNames(values);
            for (var i = 0; i < propNames.length; i++) {
                var propName = propNames[i];
                if (values[propName] === null || values[propName] === undefined) {
                    delete values[propName];
                } else if (typeof values[propName] === 'object') {
                    values[propName] = removeNulls(values[propName]);
                } else if (values[propName].length < 1) {
                    delete values[propName];
                }
            }
            return values;
        };

        var iterateValues = function (values, parent, form, isArray) {
            var i, iterateParent = [];
            Object.keys(values).forEach(function (i) {
                if (typeof values[i] === "object") {
                    iterateParent = parent.slice();
                    iterateParent.push(i);
                    iterateValues(values[i], iterateParent, form, Array.isArray(values[i]));
                } else {
                    form.append(getInput(i, values[i], parent, isArray));
                }
            });
        };

        var getInput = function (name, value, parent, array) {
            var parentString;
            if (parent.length > 0) {
                parentString = parent[0];
                var i;
                for (i = 1; i < parent.length; i += 1) {
                    parentString += "[" + parent[i] + "]";
                }

                if (array) {
                    name = parentString + "[" + name + "]";
                } else {
                    name = parentString + "[" + name + "]";
                }
            }

            return $("<input>").attr("type", "hidden")
                .attr("name", name)
                .attr("value", value);
        };


        //----------------------------------------
        // NOW THE SYNOPSIS
        //----------------------------------------
        var generatedForm = getForm(url, parameters);

        $('body').append(generatedForm);
        generatedForm.submit();
        generatedForm.remove();
    }

Oto przykład, jak z niego korzystać. Kod HTML:

<button id="testButton">Button</button>

<script>
    $(document).ready(function () {
        $("#testButton").click(function () {
            postForm({
                csrf_token: "abcd",
                rows: [
                    {
                        user_id: 1,
                        permission_group_id: 1
                    },
                    {
                        user_id: 1,
                        permission_group_id: 2
                    }
                ],
                object: {
                    apple: {
                        color: "red",
                        age: "23 days",
                        types: [
                            "golden",
                            "opal",
                        ]
                    }
                },
                the_null: null, // this will be dropped, like non-checked checkboxes are dropped
            });
        });
    });
</script>

A jeśli klikniesz przycisk testowy, opublikuje formularz i otrzymasz następujące wartości w POST:

array(3) {
  ["csrf_token"] => string(4) "abcd"
  ["rows"] => array(2) {
    [0] => array(2) {
      ["user_id"] => string(1) "1"
      ["permission_group_id"] => string(1) "1"
    }
    [1] => array(2) {
      ["user_id"] => string(1) "1"
      ["permission_group_id"] => string(1) "2"
    }
  }
  ["object"] => array(1) {
    ["apple"] => array(3) {
      ["color"] => string(3) "red"
      ["age"] => string(7) "23 days"
      ["types"] => array(2) {
        [0] => string(6) "golden"
        [1] => string(4) "opal"
      }
    }
  }
}

Uwaga: jeśli chcesz wysłać formularz do innego adresu URL niż bieżąca strona, możesz podać adres URL jako drugi argument funkcji postForm.

Na przykład (aby ponownie użyć twojego przykładu):

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

Mam nadzieję że to pomoże.

Uwaga 2: kod został pobrany z wtyczki przekierowania . Zasadniczo po prostu uprościłem to dla moich potrzeb.

molwa
źródło
-1

Wtyczka jQuery do przekierowania za pomocą POST lub GET:

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

Aby przetestować, dołącz powyższy plik .js lub skopiuj / wklej klasę do swojego kodu, a następnie użyj kodu tutaj, zastępując „argumenty” nazwami zmiennych, a „wartości” wartościami odpowiednich zmiennych:

$.redirect('demo.php', {'arg1': 'value1', 'arg2': 'value2'});
OG Sean
źródło
Zostało to również wspomniane tutaj: stackoverflow.com/questions/8389646/...
OG Sean
To rozwiązanie nadal działa dla nas dobrze. Jeśli głosujesz za jego odrzuceniem, zostaw komentarz, dlaczego.
OG Sean
-2

Możesz wykonać wywołanie AJAX (prawdopodobnie używając biblioteki takiej jak Prototype.js lub JQuery). AJAX obsługuje zarówno opcje GET, jak i POST.

Diodeus - James MacFarlane
źródło
5
Użycie XMLHttpRequest nie przekierowałoby przeglądarki na inną stronę.
Jonny Buchanan