Solicitação de postagem do JavaScript como um envio de formulário

Estou tentando direcionar um navegador para uma página diferente. Se eu quisesse um pedido GET, eu poderia dizer

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

Mas o recurso que estou tentando acessar não responderá corretamente, a menos que eu use uma solicitação POST. Se isso não fosse gerado dinamicamente, eu poderia usar o HTML

    

Então eu apenas enviaria o formulário do DOM.

Mas eu realmente gostaria de código JavaScript que me permita dizer

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

Qual é a melhor implementação de cross-browser?

Editar

Me desculpe, eu não estava claro. Eu preciso de uma solução que mude a localização do navegador, assim como enviar um formulário. Se isso for possível com XMLHttpRequest , isso não é óbvio. E isso não deve ser asynchronous, nem usar XML, então o Ajax não é a resposta.

     function post(path, params, method) { method = method || "post"; // Set method to post by default if not specified. // The rest of this code assumes you are not using a library. // It can be made less wordy if you use one. var form = document.createElement("form"); form.setAttribute("method", method); form.setAttribute("action", path); for(var key in params) { if(params.hasOwnProperty(key)) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("type", "hidden"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); form.appendChild(hiddenField); } } document.body.appendChild(form); form.submit(); } 

    Exemplo:

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

    EDIT : Desde que isso tem upvoted muito, eu estou supondo que as pessoas vão copiar muito isso muito. Então, adicionei a verificação hasOwnProperty para corrigir quaisquer erros inadvertidos.

    Esta seria uma versão da resposta selecionada usando jQuery .

     // Post to the provided URL with the specified parameters. function post(path, parameters) { var form = $('
    '); form.attr("method", "post"); form.attr("action", path); $.each(parameters, function(key, value) { var field = $(''); 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(); }

    Uma implementação simples e rápida de @Aaron answer:

     document.body.innerHTML += '
    '; document.getElementById("dynForm").submit();

    Claro, você deve preferir usar um framework JavaScript como Prototype ou jQuery …

    Usando a function createElement fornecida nesta resposta , que é necessária devido ao quebrantamento do IE com o atributo name em elementos criados normalmente com 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); } 

    A resposta de Rakesh Pai é incrível, mas há um problema que ocorre para mim (no Safari ) quando tento postar um formulário com um campo chamado submit . Por exemplo, post_to_url("http://google.com/",{ submit: "submit" } ); . Eu patched a function ligeiramente para contornar essa colisão de espaço variável.

      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! 

    Não, você não pode ter a solicitação de postagem do JavaScript como um formulário enviado.

    O que você pode ter é um formulário em HTML e enviá-lo com o JavaScript. (como explicado muitas vezes nesta página)

    Você pode criar o HTML você mesmo, você não precisa de JavaScript para escrever o HTML. Isso seria bobo se as pessoas sugerissem isso.

     

    Sua function apenas configuraria o formulário da maneira que você deseja.

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

    Então, use-o como.

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

    Mas eu apenas deixaria de fora a function e apenas faria.

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

    Finalmente, a decisão de estilo vai no arquivo ccs.

     .ninja{ display:none; } 

    Pessoalmente, acho que os formulários devem ser endereçados pelo nome, mas isso não é importante no momento.

    Se você tem Prototype instalado, você pode apertar o código para gerar e enviar o formulário oculto como este:

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

    esta é a resposta do rakesh, mas com suporte para matrizes (o que é bastante comum em formulários):

    javascript simples:

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

    Ah, e aqui está a versão jquery: (código ligeiramente diferente, mas resume-se à mesma coisa)

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

    Bem, gostaria de ter lido todos os outros posts, então não perdi tempo criando isso a partir da resposta de Rakesh Pai. Aqui está uma solução recursiva que funciona com arrays e objects. Nenhuma dependência no jQuery.

    Adicionado um segmento para lidar com casos em que o formulário inteiro deve ser enviado como uma matriz. (ou seja, onde não há object wrapper em torno de uma lista de itens)

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

    Uma solução é gerar o formulário e enviá-lo. Uma implementação é

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

    Assim, posso implementar um bookmarklet de encurtamento de URL com um simples

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

    Três opções aqui.

    1. Resposta JavaScript padrão: use uma estrutura! A maioria dos frameworks do Ajax vai te abstrair de uma maneira fácil de fazer um POST XMLHTTPRequest .

    2. Faça o pedido XMLHTTPRequest você mesmo, passando o post para o método open em vez de get. (Mais informações em Usando o método POST no XMLHTTPRequest (Ajax) .)

    3. Via JavaScript, crie dinamicamente um formulário, adicione uma ação, adicione suas inputs e envie-o.

    Aqui está como eu escrevi usando jQuery. Testado no Firefox e no Internet Explorer.

     function postToUrl(url, params, newWindow) { var form = $('
    '); form.attr('action', url); form.attr('method', 'POST'); if(newWindow){ form.attr('target', '_blank'); } var addParam = function(paramName, paramValue) { var input = $(''); input.attr({ 'id': paramName, 'name': paramName, 'value': paramValue }); form.append(input); }; // Params is an Array. if(params instanceof Array){ for(var i=0; i

    Eu iria descer a rota Ajax como outros sugeriram com algo como:

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

    A maneira mais fácil é usar o Ajax Post Request:

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

    Onde:

    • dados são um object
    • dataType são os dados esperados pelo servidor (xml, json, script, text, html)
    • url é o endereço do seu servidor RESt ou qualquer function no lado do servidor que aceite o HTTP-POST.

    Em seguida, no manipulador de sucesso, redirecione o navegador com algo como window.location.

    A biblioteca Prototype inclui um object Hashtable, com um método “.toQueryString ()”, que permite transformar facilmente um object / estrutura JavaScript em uma string de estilo de string de consulta. Como a postagem exige que o “corpo” da solicitação seja uma string formatada em string de consulta, isso permite que sua solicitação do Ajax funcione corretamente como uma postagem. Aqui está um exemplo usando 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(); }; 

    Isso funciona perfeitamente no meu caso:

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

    Você pode usá-lo em function como:

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

    Usando isso, você pode postar todos os valores das inputs.

    Isto é como a opção 2 de Alan (acima). Como instanciar o httpobj é deixado como um exercício.

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

    Isso é baseado no código do beauSD usando jQuery. Ele é aprimorado para funcionar recursivamente nos objects.

     function post(url, params, urlEncoded, newWindow) { var 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 $('').attr({name: fullname, value: value}).appendTo(form); }; addParam('', params, ''); $('body').append(form); form.submit(); } 

    Você pode adicionar dinamicamente o formulário usando DHTML e, em seguida, enviar.

    Você poderia usar uma biblioteca como o jQuery e seu método $ .post .

    FormObject é uma opção. Mas o FormObject não é suportado pela maioria dos navegadores agora.

    Ainda outra solução recursiva , uma vez que alguns dos outros parecem estar quebrados (eu não testei todos eles). Este depende do lodash 3.xe do ES6 (o jQuery não é obrigatório):

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

    Eu uso o document.forms java e loop-lo para obter todos os elementos no formulário, em seguida, envie via xhttp. Portanto, esta é a minha solução para o envio de javascript / ajax (com todo o html incluído como exemplo):

         
    First name:
    Last name:
    Addr1:
    City:

    O método que eu uso para postar e direcionar um usuário automaticamente para outra página é apenas escrever um formulário oculto e depois submetê-lo automaticamente. Tenha certeza de que a forma oculta não ocupa absolutamente nenhum espaço na página da web. O código seria algo assim:

      
    document.getElementById('fielda').value="some text for field a"; document.getElementById('fieldb').innerHTML="some text for multiline fieldb"; form1.submit();

    Aplicação de envio automático

    Uma aplicação de um envio automático seria direcionar valores de formulário que o usuário coloca automaticamente na outra página de volta para essa página. Tal aplicação seria assim:

     fieldapost= if (fieldapost !="") { document.write("
    "); document.getElementById('fielda').value=fieldapost; form1.submit(); }

    Aqui está como eu faço isso.

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

    Plugin jQuery para redirect com POST ou GET:

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

    Para testar, inclua o arquivo .js ou copie / cole a class em seu código, use o código aqui, substituindo “args” pelos nomes das variables ​​e “values” pelos valores das respectivas variables:

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

    Você poderia fazer uma chamada AJAX (provavelmente usando uma biblioteca como Prototype.js ou JQuery). O AJAX pode manipular as opções GET e POST.