formularios - Solicitud de publicación de JavaScript como un formulario de envío
formulario javascript ejemplo (28)
Así es como lo escribí usando jQuery. Probado en Firefox e 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();
}
Estoy tratando de dirigir un navegador a una página diferente. Si quisiera una solicitud GET, podría decir
document.location.href = ''http://example.com/q=a'';
Pero el recurso al que estoy tratando de acceder no responderá correctamente a menos que use una solicitud POST. Si esto no fuera generado dinámicamente, podría usar el HTML
<form action="http://example.com/" method="POST">
<input type="hidden" name="q" value="a">
</form>
Entonces simplemente enviaría el formulario desde el DOM.
Pero realmente me gustaría el código JavaScript que me permite decir.
post_to_url(''http://example.com/'', {''q'':''a''});
¿Cuál es la mejor implementación de navegador cruzado?
Editar
Lo siento, no estaba claro. Necesito una solución que cambie la ubicación del navegador, al igual que enviar un formulario. Si esto es posible con XMLHttpRequest , no es obvio. Y esto no debe ser asíncrono, ni utilizar XML, por lo que Ajax no es la respuesta.
Así es como lo hago.
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();
}
Bueno, ojalá hubiera leído todas las otras publicaciones, así que no perdí tiempo creando esto de la respuesta de Rakesh Pai. Aquí hay una solución recursiva que funciona con matrices y objetos. No hay dependencia de jQuery.
Se agregó un segmento para manejar los casos en los que todo el formulario debe enviarse como una matriz. (es decir, donde no hay un objeto envoltorio alrededor de una lista de elementos)
/**
* 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();
};
El método que utilizo para publicar y dirigir a un usuario automáticamente a otra página es simplemente escribir un formulario oculto y luego enviarlo automáticamente. Tenga la seguridad de que la forma oculta no ocupa espacio alguno en la página web. El código sería algo como esto:
<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();
Solicitud de envío automático
Una aplicación de un envío automático sería dirigir los valores de formulario que el usuario colocará automáticamente en la otra página a esa página. Tal aplicación sería así:
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();
}
Esta es la respuesta de rakesh, pero con soporte para arreglos (que es bastante común en las formas):
javascript simple
function post_to_url(path, params, method) {
method = method || "post"; // Set method to post by default, if not specified.
// The rest of this code assumes you are not using a library.
// It can be made less wordy if you use one.
var form = document.createElement("form");
form.setAttribute("method", method);
form.setAttribute("action", path);
var addField = function( key, value ){
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", value );
form.appendChild(hiddenField);
};
for(var key in params) {
if(params.hasOwnProperty(key)) {
if( params[key] instanceof Array ){
for(var i = 0; i < params[key].length; i++){
addField( key, params[key][i] )
}
}
else{
addField( key, params[key] );
}
}
}
document.body.appendChild(form);
form.submit();
}
Ah, y aquí está la versión jquery: (código ligeramente diferente, pero se reduce a lo mismo)
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();
}
Esta sería una versión de la respuesta seleccionada usando 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();
}
Esto es como la opción 2 de Alan (arriba). Cómo instanciar el httpobj se deja como ejercicio.
httpobj.open("POST", url, true);
httpobj.setRequestHeader(''Content-Type'',''application/x-www-form-urlencoded; charset=UTF-8'');
httpobj.onreadystatechange=handler;
httpobj.send(post);
Esto funciona perfectamente en mi caso:
document.getElementById("form1").submit();
Puedes usarlo en función como:
function formSubmit() {
document.getElementById("frmUserList").submit();
}
Usando esto puedes publicar todos los valores de las entradas.
Esto se basa en el código de beauSD usando jQuery. Se mejora por lo que funciona recursivamente en objetos.
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();
}
Iría por la ruta del Ajax como otros sugirieron con 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");
La biblioteca Prototype incluye un objeto Hashtable, con un método ".toQueryString ()", que le permite convertir fácilmente un objeto / estructura de JavaScript en una cadena de estilo de cadena de consulta. Dado que la publicación requiere que el "cuerpo" de la solicitud sea una cadena con formato de cadena de consulta, esto permite que su solicitud Ajax funcione correctamente como una publicación. Aquí hay un ejemplo 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();
};
La forma más fácil es usar Ajax Post Request:
$.ajax({
type: "POST",
url: ''http://www.myrestserver.com/api'',
data: data,
success: success,
dataType: dataType
});
dónde:
- los datos son un objeto
- dataType es la información esperada por el servidor (xml, json, script, text, html)
- url es la dirección de su servidor RESt o cualquier función en el lado del servidor que acepte el HTTP-POST.
Luego, en el controlador de éxito, redirija el navegador con algo como window.location.
Mi solución codificará objetos profundamente anidados, a diferencia de la solución actualmente aceptada por @RakeshPai.
Utiliza la biblioteca npm ''qs'' y su función de clasificación para convertir objetos anidados en parámetros.
Este código funciona bien con un back-end de Rails, aunque debería ser capaz de modificarlo para que funcione con cualquier backend que necesite modificando las opciones pasadas a stringificar. Rails requiere que arrayFormat esté configurado en "corchetes".
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();
}
Ejemplo:
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"]
}
]
});
Produce estos parámetros de 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"]}]}
No, no puede tener la solicitud de publicación de JavaScript como un formulario de envío.
Lo que puede tener es un formulario en HTML, luego envíelo con el JavaScript. (como se explica muchas veces en esta página)
Puede crear el HTML usted mismo, no necesita JavaScript para escribir el HTML. Eso sería una tontería si la gente lo sugiriera.
<form id="ninja" action="http://example.com/" method="POST">
<input id="donaldduck" type="hidden" name="q" value="a">
</form>
Su función solo configurará la forma de la manera que usted lo desee.
function postToURL(a,b,c){
document.getElementById("ninja").action = a;
document.getElementById("donaldduck").name = b;
document.getElementById("donaldduck").value = c;
document.getElementById("ninja").submit();
}
Entonces, úsalo como.
postToURL("http://example.com/","q","a");
Pero solo dejaría fuera la función y solo haría.
document.getElementById(''donaldduck'').value = "a";
document.getElementById("ninja").submit();
Finalmente, la decisión de estilo va en el archivo ccs.
.ninja{
display:none;
}
Personalmente creo que las formas deben ser tratadas por nombre, pero eso no es importante ahora.
Otra solución recursiva , ya que algunas de las otras parecen estar rotas (no las probé todas). Este depende de lodash 3.x y ES6 (no se requiere 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();
}
Plugin jQuery para redireccionar con POST o GET:
github.com/mgalante/jquery.redirect/blob/master/…
Para probar, incluya el archivo .js anterior o copie / pegue la clase en su código, luego use el código aquí, reemplazando "args" con sus nombres de variable y "valores" con los valores de esas variables respectivas:
$.redirect(''demo.php'', {''arg1'': ''value1'', ''arg2'': ''value2''});
Podría hacer una llamada AJAX (probablemente utilizando una biblioteca como Prototype.js o JQuery). AJAX puede manejar las opciones GET y POST.
Podría usar una biblioteca como jQuery y su método $ .post .
Podrías agregar dinámicamente el formulario usando DHTML y luego enviarlo.
Si tiene instalado Prototype , puede ajustar el código para generar y enviar el formulario oculto de la siguiente manera:
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();
Tres opciones aquí.
Respuesta estándar de JavaScript: ¡Usa un marco! La mayoría de los frameworks Ajax lo habrán abstraído de una manera fácil de hacer un POST XMLHttpRequest .
Realice la solicitud XMLHTTPRequest usted mismo, pasando la publicación al método abierto en lugar de obtener. (Más información en Uso del método POST en XMLHTTPRequest (Ajax) .)
A través de JavaScript, cree dinámicamente un formulario, agregue una acción, agregue sus entradas y envíe eso.
Una implementación simple y rápida de la respuesta de @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();
Por supuesto, deberías usar un marco de JavaScript como Prototype o jQuery ...
Una solución es generar el formulario y enviarlo. Una implementación es
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();
}
Así que puedo implementar un bookmarklet de acortamiento de URL con un simple
javascript:post_to_url(''http://is.gd/create.php'', {''URL'': location.href});
Usando la función createElement
proporcionada en esta respuesta , que es necesaria debido a la rotura de IE con el atributo de nombre en elementos creados normalmente con 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);
}
Utilizo document.forms java y lo hago en bucle para obtener todos los elementos del formulario, luego enviarlo a través de xhttp. Así que esta es mi solución para el envío de javascript / ajax (con todos los html incluidos como ejemplo):
<!DOCTYPE html>
<html>
<body>
<form>
First name: <input type="text" name="fname" value="Donald"><br>
Last name: <input type="text" name="lname" value="Duck"><br>
Addr1: <input type="text" name="add" value="123 Pond Dr"><br>
City: <input type="text" name="city" value="Duckopolis"><br>
</form>
<button onclick="smc()">Submit</button>
<script>
function smc() {
var http = new XMLHttpRequest();
var url = "yourphpfile.php";
var x = document.forms[0];
var xstr = "";
var ta ="";
var tb ="";
var i;
for (i = 0; i < x.length; i++) {
if (i==0){ta = x.elements[i].name+"="+ x.elements[i].value;}else{
tb = tb+"&"+ x.elements[i].name +"=" + x.elements[i].value;
} }
xstr = ta+tb;
http.open("POST", url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
// do whatever you want to with the html output response here
}
}
http.send(xstr);
}
</script>
</body>
</html>
La respuesta de Rakesh Pai es sorprendente, pero hay un problema que me ocurre (en Safari ) cuando intento publicar un formulario con un campo llamado submit
. Por ejemplo, post_to_url("http://google.com/",{ submit: "submit" } );
. He parcheado la función ligeramente para caminar alrededor de esta colisión de espacio variable.
function post_to_url(path, params, method) {
method = method || "post";
var form = document.createElement("form");
//Move the submit function to another variable
//so that it doesn''t get overwritten.
form._submit_function_ = form.submit;
form.setAttribute("method", method);
form.setAttribute("action", path);
for(var key in params) {
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", params[key]);
form.appendChild(hiddenField);
}
document.body.appendChild(form);
form._submit_function_(); //Call the renamed function.
}
post_to_url("http://google.com/", { submit: "submit" } ); //Works!
FormData es una opción. Pero FormObject no es compatible con la mayoría de los navegadores ahora.
/**
* 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) {
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();
}
Ejemplo:
post(''/contact/'', {name: ''Johnny Bravo''});
EDITAR : Ya que esto se ha elevado tanto en las votaciones, supongo que la gente copiará esto mucho. Así que agregué la verificación hasOwnProperty
para corregir cualquier error involuntario.