Вопрос

Я пытаюсь перенаправить браузер на другую страницу.Если бы мне нужен был запрос 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 - это не ответ.

Это было полезно?

Решение

Динамически создавать <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 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();
}

Пример:

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

Редактировать:Поскольку за это так много проголосовали, я предполагаю, что люди будут часто копировать и вставлять это.Поэтому я добавил hasOwnProperty проверьте, исправлены ли любые непреднамеренные ошибки.

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

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

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

Используя 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);
}

Ответ Ракеша Пая удивительно, но есть проблема, которая возникает у меня (в Сафари) когда я пытаюсь опубликовать форму с полем под названием 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!

Нет.У вас не может быть запроса JavaScript post, подобного отправке формы.

Что у вас может быть, так это форма в 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;
}

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

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

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

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

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

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

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

Что ж, жаль, что я не прочитал все остальные сообщения, чтобы не терять время на создание этого из ответа Ракеша Пая.Вот рекурсивное решение, которое работает с массивами и объектами.Никакой зависимости от 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();
};

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

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

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

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

Я бы пошел по пути 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");

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

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

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

где:

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

Затем в обработчике успеха перенаправьте браузер чем-то вроде window.Расположение.

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

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

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

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

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

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

Формообъект это вариант.Но formObject сейчас не поддерживается большинством браузеров.

Еще один рекурсивный решение, поскольку некоторые из других, похоже, сломаны (я не тестировал их все).Это зависит от лодаш 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();
}

Мое решение будет кодировать глубоко вложенные объекты, в отличие от принятого в настоящее время решения @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"]}]}

Это похоже на вариант Алана 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);

Это основано на коде 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();
}

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

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

Я использую document.forms java и зацикливаю его, чтобы получить все элементы в форме, затем отправляю через 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>

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top