Запрос на отправку JavaScript как отправка формы

Я пытаюсь перенаправить браузер на другую страницу. Если бы я хотел получить запрос GET, я бы сказал

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

Но ресурс, к которому я пытаюсь получить доступ, не будет отвечать должным образом, если я не использую запрос POST. Если бы это не было динамически сгенерировано, я мог бы использовать HTML

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

Затем я просто отправлял форму из DOM.

Но на самом деле мне нужен код JavaScript, который позволяет мне сказать

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

Какая лучшая кроссбраузерная реализация?

Редактировать

Мне жаль, что я не понял. Мне нужно решение, которое меняет расположение браузера, как при отправке формы. Если это возможно с XMLHttpRequest, это не очевидно. И это не должно быть асинхронным или использовать XML, поэтому Ajax - не ответ.

Как упоминалось в другом потоке, существует плагин jquery ".redirect", который работает с методом POST или GET. Он создает форму со скрытыми входами и отправляет ее за вас. Пример: $ .redirect ('demo.php', {'arg1': 'value1', 'arg2': 'value2'}); github.com/mgalante/jquery.redirect/blob/master/…

OG Sean 09.07.2018 03:16

У объекта document нет location.href, необходимого для использования window.

Justin Liu 12.06.2020 18:07
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1 618
2
1 578 055
31
Перейти к ответу Данный вопрос помечен как решенный

Ответы 31

Вы можете динамически добавить форму с помощью DHTML, а затем отправить.

Вы можете сделать вызов AJAX (вероятно, используя библиотеку, такую ​​как Prototype.js или JQuery). AJAX может обрабатывать параметры как GET, так и POST.

Использование XMLHttpRequest не направляет браузер на другую страницу.

Jonny Buchanan 25.09.2008 19:35

Вы можете использовать такую ​​библиотеку, как jQuery и ее $ .post метод.

Обратите внимание, что $ .post - это только AJAX.

Bryan Larsen 27.03.2012 16:49

Здесь три варианта.

  1. Стандартный ответ JavaScript: используйте фреймворк! Большинство фреймворков Ajax предоставят вам простой способ сделать XMLHTTPRequest POST.

  2. Сделайте запрос XMLHTTPRequest самостоятельно, передав сообщение в метод open вместо get. (Дополнительная информация в Использование метода POST в XMLHTTPRequest (Ajax).)

  3. С помощью JavaScript динамически создайте форму, добавьте действие, добавьте свои данные и отправьте их.

XMLHTTPRequest не обновляет окно. Вы хотите сказать, что я должен закончить AJAX с помощью document.write (http.responseText)?

Joseph Holsten 25.09.2008 20:12

Зачем добавлять в проект 30k +, если он больше ничего не делает с фреймворком?

Rafael Herscovici 07.11.2011 19:26

Библиотека Прототип включает объект Hashtable с методом «.toQueryString ()», который позволяет легко преобразовать объект / структуру JavaScript в строку стиля строки запроса. Поскольку сообщение требует, чтобы "тело" запроса было строкой в ​​формате строки запроса, это позволяет вашему запросу Ajax правильно работать как сообщение. Вот пример использования 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();
};

Это решение - одно из немногих, в котором текущий отображаемый документ не заменяется ответом сервера.

dothebart 30.12.2015 19:54
Ответ принят как подходящий

Динамически создавать <input> в форме и отправлять ее

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

Пример:

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

РЕДАКТИРОВАТЬ: Поскольку за это так много проголосовали, я предполагаю, что люди будут часто копировать это. Поэтому я добавил проверку hasOwnProperty, чтобы исправить любые непреднамеренные ошибки.

А как насчет массивов в параметрах данных? JQuery post () интерпретирует, например: "data: {array: [1, 2, 3]}" как? Array = 1 & array = 2 & array = 3. Этот код дает другой результат.

Scit 14.10.2015 09:36

Предупреждение: несмотря на множество положительных отзывов, это решение ограничено и не обрабатывает массивы или вложенные объекты внутри формы. В противном случае это отличный ответ.

emragins 20.10.2015 19:41

Я создал суть с кодом gist.github.com/lingceng/175f493450636e505cc3

lingceng 21.11.2015 12:19

удивительно, что это изначально не поддерживается ни html, ни javascript, ни jquery .. вы должны это закодировать.

eugene 17.02.2016 11:02

Стоит ли удалять форму после того, как она была добавлена ​​в DOM? Могу предвидеть проблемы с document.forms

mricci 06.05.2016 03:33

почему метод находится в параметрах, так как он называется постом и должен использоваться только для поста?

Srneczek 31.05.2016 20:19

Нет возможности смоделировать этот эффект с помощью ajax? Какая магия в HTML-форме позволяет добиться этого, что без нее этого не обойтись?

temporary_user_name 24.06.2016 21:02

Если вы хотите, чтобы этот пост появился в новой вкладке: var tabWindowId = window.open('about:blank', '_blank'); var form = tabWindowId.document.createElement("form"); tabWindowId.document.body.appendChild(form);

Deunz 28.06.2016 10:59

@mricci Цель этого фрагмента - перенаправить браузер на новый URL-адрес, указанный действием; если вы остаетесь на той же странице, вы можете просто использовать традиционный AJAX для POST ваших данных. Поскольку браузер должен переходить на новую страницу, содержимое DOM текущей страницы не имеет значения.

Ken Bellows 07.07.2016 16:07

@Aerovistae Разница в том, что AJAX не переходит на новую страницу, а просто возвращает данные скрипту, который сделал запрос. Гипотетически вы, вероятно, могли бы подделать его, сделав запрос AJAX POST с типом содержимого, установленным на "text / html", чтобы получить содержимое новой страницы, а затем заменить текущую страницу на HTML, который вы получите обратно, но URL-адрес не будет изменится, и разве сама идея не заставит вас немного заткнуть рот? (При этом аналогичные методы используются для разделы страниц в фреймворках одностраничных приложений, таких как Angular и Ember)

Ken Bellows 07.07.2016 16:11

@RakeshPai Почему у вас есть входной аргумент 'method', когда он предназначен только для 'POST'?

Ethan 08.07.2017 05:22

@Ethan Это необязательный аргумент, по умолчанию используется POST. Смена методов ничего не стоит, поэтому я просто вставил это туда. Не стесняйтесь снимать его, если он вас беспокоит.

Rakesh Pai 10.07.2017 12:01

@stevemao зависит от того, нужно ли вам поддерживать IE6-9 или нет

Andy 01.11.2017 01:50

Пользователи Python, Django и, возможно, Flask увидят эту ошибку: «Запрещено (403). Ошибка проверки CSRF. Запрос прерван.», Если создается форма с нуля. В этом случае вы должны передать токен csrf следующим образом: post ('/ contact /', {name: 'Johnny Bravo', csrfmiddlewaretoken: $ ("# csrf_token"). Val ()});

Davidson Lima 22.11.2017 19:09

Разве это не должно быть "POST" в верхнем регистре (в строке method = method || "post")? Я никогда не пробовал строчные буквы, но, думаю, большинству IIS наплевать. Я знаю один IIS, в котором строчные буквы не работают.

www-0av-Com 02.01.2018 15:42

Привет, работает очень хорошо. Но он всегда создает новый элемент var form = document.createElement("form");. Есть ли возможность добавить его к уже существующему методу POST?

Damian Silkowski 26.01.2018 15:48

Если значение содержит опасный символ xml, это не будет работать в ASP.NET encodeUriComponent (значение) требуется. Затем UrlDecode также требуется на стороне сервера.

Stefan Steiger 13.03.2018 19:27

@ www-0av-Com. post здесь не HTTP-команда, а метод формы, который нечувствителен к регистру. <form method = "post"> вполне приемлем.

TRiG 21.11.2019 19:06

@ Ракеш и все, может кто-нибудь здесь поможет, пожалуйста: stackoverflow.com/questions/61313006/…

shireef khatab 20.04.2020 13:38

Умное решение. Вместо того, чтобы использовать JS для создания формы, я вручную создал форму и добавил к ней скрытый атрибут с только для чтения в текстовых полях. Затем я использовал JS, чтобы заполнить форму и отправить ее.

Haddock-san 22.04.2020 18:21

Итак, вы говорите мне, что в JavaScript нет способа сделать обычный запрос POST без этого HTML-хака?

Lorenzo Von Matterhorn 23.10.2020 10:22

Использование функции createElement, представленной в этот ответ, которая необходима из-за Нарушение IE с атрибутом name для элементов, обычно создаваемых с помощью 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);
}

Вам нужно удалить ребенка после подачи? Страница все равно не уходит?

Nils 01.06.2012 02:31

Нет смысла удалять ребенка после отправки, за исключением случаев, когда используется сеанс и эти данные сохраняются.

Miloš 20.07.2012 11:07

@CantucciHQ Страница может оставаться неизменной, даже если цель формы не установлена. Например, есть 204 Нет содержимого.

Eugene Ryabtsev 30.01.2014 15:41

Простая быстрая и грязная реализация ответа @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();

Конечно, вам лучше использовать фреймворк JavaScript, такой как Прототип или jQuery ...

Есть ли способ сделать это без загрузки веб-страницы в текущем окне / вкладке браузера?

pbreitenbach 25.09.2010 00:37

Как мне вставить сюда csrf?

Shulz 20.09.2020 13:29

@Shulz Вы можете добавить еще один скрытый ввод с [name], установленным для ключа, и [value], установленным для значения токена.

Amir Savand 14.12.2020 00:40

Я бы пошел по маршруту Ajax, как предлагали другие, с чем-то вроде:

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

Uncaught ReferenceError: QueryString не определен.

Chase Roberts 12.05.2015 06:34

Это похоже на вариант 2 Алана (см. Выше). Как создать экземпляр httpobj оставлено как упражнение.

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

Одно из решений - создать форму и отправить ее. Одна реализация

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

Таким образом, я могу реализовать букмарклет для сокращения URL-адресов с помощью простого

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

Если у вас установлен Прототип, вы можете усилить код, чтобы сгенерировать и отправить скрытую форму следующим образом:

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

Ответ Ракеша Пая замечательно, но у меня возникает проблема (в Сафари), когда я пытаюсь опубликовать форму с полем submit. Например, post_to_url("http://google.com/",{ submit: "submit" } );. Я немного исправил функцию, чтобы обойти это столкновение с переменным пространством.

    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!

2018 и все еще не лучший ответ?

iiirxs 20.06.2018 16:35

Есть ли в Safari проблема, требующая решения?

Flimm 13.10.2020 22:48

Вот как я написал это с помощью jQuery. Протестировано в Firefox и 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();
}

Работал у меня. Спасибо. (Проверено в Chrome)

dannie.f 23.12.2010 16:43

Я думаю, проблема здесь может заключаться в том, что форма удаляется до того, как отправка возвращается. Я слышал, что в некоторых браузерах, если вы переместите или удалите форму до завершения отправки, обработчики не сработают. Вместо этого удалите форму из документа в обработчике.

Jeff DQ 12.05.2011 04:18

Работает как шарм. Протестировано в Firefox + Chrome + IE11 - Большое спасибо за это!

Deunz 28.06.2016 14:41

Это будет версия выбранного ответа с использованием 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();
}

Немного изменено это для поддержки массивов и объектов gist.github.com/hom3chuk/692bf12fe7dac2486212

НЛО 29.09.2015 01:39

Если значение содержит опасный символ xml, это не будет работать в ASP.NET encodeUriComponent (значение) требуется. Затем UrlDecode также требуется на стороне сервера.

Stefan Steiger 13.03.2018 19:26

Если ваши потребности просты, то в этой функции нет необходимости. Однострочного достаточно: $("<form method='POST' action='https://example.com'><input type='hidden' name='q' value='a'/></form>").appendTo("body").submit();

rinogo 17.07.2019 22:31

Это основано на коде beauSD с использованием jQuery. Он улучшен, поэтому он рекурсивно работает с объектами.

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

это ответ rakesh, но с поддержкой массивов (что довольно часто встречается в формах):

простой 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();
}

о, и вот версия jquery: (немного другой код, но сводится к одному и тому же)

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

p.s. Теперь мне нравится использовать эту функцию, но вместо того, чтобы отправлять форму в конце, я просто возвращаю ее обратно вызывающему. таким образом я могу легко установить дополнительные атрибуты или сделать с ним что-то еще, если это необходимо.

kritzikratzi 26.05.2012 20:09

Большой! очень полезный. Небольшое изменение для людей, которые полагаются на PHP на стороне сервера этой формы, я изменил addField (key, params [key] [i]) на addField (key + '[]', params [key] [i]). Это делает $ _POST [ключ] доступным в виде массива.

Thava 18.11.2013 05:07

@Thava вы также можете установить name = "bla []" в поле ввода. в любом случае, есть языки, отличные от php, которые не поддерживают синтаксис [], поэтому я оставляю это без изменений.

kritzikratzi 18.11.2013 08:20

В моем случае это отлично работает:

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

Вы можете использовать его в таких функциях, как:

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

Используя это, вы можете опубликовать все значения входов.

Нет. У вас не может быть запроса на публикацию JavaScript, как отправки формы.

Вы можете создать форму в HTML, а затем отправить ее с помощью JavaScript. (как много раз объяснялось на этой странице).

Вы можете создать HTML самостоятельно, вам не нужен JavaScript для написания HTML. Было бы глупо, если бы люди это предложили.

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

Ваша функция просто настроит форму так, как вы этого хотите.

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

Затем используйте это как.

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

Но я бы просто оставил функцию и просто сделал.

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

Наконец, решение о стиле находится в файле ccs.

#ninja{ 
  display:none;
}

Лично я считаю, что к формам следует обращаться по имени, но сейчас это не важно.

Самый простой способ - использовать Ajax Post Request:

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

где:

  • данные - это объект
  • dataType - это данные, ожидаемые сервером (xml, json, скрипт, текст, html)
  • url - это адрес вашего сервера RESt или любой функции на стороне сервера, которая принимает HTTP-POST.

Затем в обработчике успеха перенаправьте браузер с помощью чего-то вроде window.location.

Вы не упомянули, что предлагаемый вами подход основан на библиотеке JavaScript jQuery.

DavidRR 15.12.2013 05:32

вы также упустили суть вопроса - он хочет «направить браузер на другую страницу», а не делать запрос ajax.

Black 03.04.2014 04:21

Вы можете дождаться ответа, а затем document.location = {url}; Единственное место, где я могу представить, что это не сработает, - это если вы перенаправляетесь на загрузку файла.

Epirocks 21.03.2017 13:42

Что ж, жаль, что я не прочитал все другие сообщения, чтобы не терять время, создавая это из ответа Ракеша Пая. Вот рекурсивное решение, которое работает с массивами и объектами. Нет зависимости от jQuery.

Добавлен сегмент для обработки случаев, когда вся форма должна быть отправлена ​​как массив. (т.е. там, где нет объекта-оболочки вокруг списка элементов)

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

Похоже, это тоже неправильно кодирует вложенные объекты.

mpen 11.05.2016 21:05

@mpen у тебя есть рабочий пример?

emragins 11.05.2016 23:47

Нет извините. Писать самому было достаточно легко; не стоит тратить время на отладку.

mpen 12.05.2016 00:21

FormObject - это опция. Но FormObject сейчас не поддерживается большинством браузеров.

Еще одно решение рекурсивный, поскольку некоторые из них кажутся неисправными (я не тестировал их все). Это зависит от lodash 3.x и ES6 (jQuery не требуется):

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

Метод, который я использую для публикации и автоматического направления пользователя на другую страницу, - это просто написать скрытую форму и затем автоматически отправить ее. Будьте уверены, что скрытая форма абсолютно не занимает места на веб-странице. Код будет примерно таким:

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

Применение автоматической отправки

Приложение автоматической отправки будет направлять значения формы, которые пользователь автоматически помещает на другую страницу, обратно на эту страницу. Такое приложение было бы таким:

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

Я использую java document.forms и зацикливаю его, чтобы получить все элементы в форме, а затем отправляю через xhttp. Итак, это мое решение для отправки javascript / ajax (со всем включенным html в качестве примера):

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

Вот как я это делаю.

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

Плагин jQuery для перенаправления с помощью POST или GET:

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

Для тестирования включите указанный выше файл .js или скопируйте / вставьте класс в свой код, затем используйте приведенный здесь код, заменив «args» на имена переменных, а «values» - на значения этих переменных:

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

Это также упоминалось здесь: stackoverflow.com/questions/8389646/…

OG Sean 09.07.2018 03:22

Мое решение будет кодировать глубоко вложенные объекты, в отличие от принятого в настоящее время решения от @RakeshPai.

Он использует библиотеку npm qs и ее функцию stringify для преобразования вложенных объектов в параметры.

Этот код хорошо работает с серверной частью Rails, хотя вы должны иметь возможность модифицировать его для работы с любым нужным вам сервером, изменив параметры, переданные в stringify. Rails требует, чтобы arrayFormat был установлен в «скобки».

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

Пример:

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

Производит следующие параметры 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"]}]}

Это отлично сработало для меня с вложенными объектами / значениями массивов, спасибо

sMyles 10.12.2020 02:39

@sMyles Это очень ценится и, возможно, впервые здесь кто-то сказал спасибо :-)

cmrichards 18.01.2021 05:09

Вы можете использовать метод триггера jQuery для отправки формы, точно так же, как вы нажимаете кнопку, например,

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

он будет отправлен в браузере.

Для этого вам даже не нужен jQuery. document.querySelector("form").submit() будет таким же с любой дополнительной структурой

Ulrich Stark 05.02.2021 16:24

Ни одно из вышеперечисленных решений не обрабатывало глубоко вложенные параметры только с помощью jQuery, Итак, вот мое решение за два цента.

Если вы используете jQuery и вам нужно обрабатывать глубоко вложенные параметры, вы можете использовать эту функцию ниже:

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

Вот пример того, как его использовать. 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>

И если вы нажмете кнопку тестирования, он опубликует форму, и вы получите следующие значения в 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"
      }
    }
  }
}

Примечание: если вы хотите опубликовать форму по URL-адресу, отличному от текущей страницы, вы можете указать URL-адрес в качестве второго аргумента функции postForm.

Так, например (чтобы повторно использовать ваш пример):

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

Надеюсь это поможет.

Примечание 2: код был взят из плагин перенаправления. Я просто упростил это для моих нужд.

Пытаться

function post_to_url(url, obj) {
  let id=`form_${+new Date()}`;
  document.body.innerHTML+=`
    <form id = "${id}" action = "${url}" method = "POST">
      ${Object.keys(obj).map(k=>`
        <input type = "hidden" name = "${k}" value = "${obj[k]}">
      `)}
    </form>`
  this[id].submit();  
}

// TEST - in second param object can have more keys
function jump() { post_to_url('https://example.com/', {'q':'a'}); }
Open chrome>networks and push button:
<button onclick = "jump()">Send POST</button>

Другие вопросы по теме