Respuestas:
Los formularios XHTML 1.x solo admiten GET y POST. GET y POST son los únicos valores permitidos para el atributo "método".
De acuerdo con el estándar HTML , puede que no . Los únicos valores válidos para el atributo del método son get
y post
, correspondientes a los métodos HTTP GET y POST. <form method="put">
es HTML no válido y será tratado como <form>
, es decir, enviará una solicitud GET.
En cambio, muchos marcos simplemente usan un parámetro POST para tunelizar el método HTTP:
<form method="post" ...>
<input type="hidden" name="_method" value="put" />
...
Por supuesto, esto requiere desenvolver del lado del servidor.
¿Puedo usar el método "Put" en formato html para enviar datos desde el formulario HTML al servidor?
Sí, puede, pero tenga en cuenta que no dará como resultado una PUT sino una solicitud GET. Si usa un valor no válido para el method
atributo de la <form>
etiqueta, el navegador usará el valor predeterminado get
.
Los formularios HTML (hasta HTML versión 4 (5 Draft) y XHTML 1) solo admiten GET y POST como métodos de solicitud HTTP. Una solución para esto es hacer un túnel de otros métodos a través de POST mediante el uso de un campo de formulario oculto que es leído por el servidor y la solicitud se despacha en consecuencia. XHTML 2.0 una vez planeó admitir GET, POST, PUT y DELETE para formularios, pero entrará en XHTML5 de HTML5 , que no planea admitir PUT. [actualización para]
Alternativamente, puede ofrecer un formulario, pero en lugar de enviarlo, cree y active un XMLHttpRequest utilizando el método PUT con JavaScript.
PUT /resource
.
HttpRequest.getParameterMap()
que no devolvió los parámetros del formulario.
_method
solución de campo oculto
La siguiente técnica simple es utilizada por algunos marcos web:
agregue un _method
parámetro oculto a cualquier formulario que no sea GET o POST:
<input type="hidden" name="_method" value="PUT">
Esto se puede hacer automáticamente en marcos a través del método auxiliar de creación HTML.
arregle el método de formulario real a POST ( <form method="post"
)
procesa _method
en el servidor y hace exactamente como si ese método hubiera sido enviado en lugar de la POST real
Puedes lograr esto en:
form_tag
@method("PATCH")
Justificación / historia de por qué no es posible en HTML puro: /software/114156/why-there-are-no-put-and-delete-methods-in-html-forms
@method("PATCH")
POST
y no lo que realmente necesitaba.
Desafortunadamente, los navegadores modernos no ofrecen soporte nativo para solicitudes HTTP PUT. Para evitar esta limitación, asegúrese de que el atributo de método de su formulario HTML sea "post", luego agregue un parámetro de anulación de método a su formulario HTML como este:
<input type="hidden" name="_METHOD" value="PUT"/>
Para probar sus solicitudes, puede usar "Postman", una extensión de Google Chrome
Para configurar los métodos PUT y DELETE, realizo lo siguiente:
<form
method="PUT"
action="domain/route/param?query=value"
>
<input type="hidden" name="delete_id" value="1" />
<input type="hidden" name="put_id" value="1" />
<input type="text" name="put_name" value="content_or_not" />
<div>
<button name="update_data">Save changes</button>
<button name="remove_data">Remove</button>
</div>
</form>
<hr>
<form
method="DELETE"
action="domain/route/param?query=value"
>
<input type="hidden" name="delete_id" value="1" />
<input type="text" name="delete_name" value="content_or_not" />
<button name="delete_data">Remove item</button>
</form>
Entonces JS actúa para realizar los métodos deseados:
<script>
var putMethod = ( event ) => {
// Prevent redirection of Form Click
event.preventDefault();
var target = event.target;
while ( target.tagName != "FORM" ) {
target = target.parentElement;
} // While the target is not te FORM tag, it looks for the parent element
// The action attribute provides the request URL
var url = target.getAttribute( "action" );
// Collect Form Data by prefix "put_" on name attribute
var bodyForm = target.querySelectorAll( "[name^=put_]");
var body = {};
bodyForm.forEach( element => {
// I used split to separate prefix from worth name attribute
var nameArray = element.getAttribute( "name" ).split( "_" );
var name = nameArray[ nameArray.length - 1 ];
if ( element.tagName != "TEXTAREA" ) {
var value = element.getAttribute( "value" );
} else {
// if element is textarea, value attribute may return null or undefined
var value = element.innerHTML;
}
// all elements with name="put_*" has value registered in body object
body[ name ] = value;
} );
var xhr = new XMLHttpRequest();
xhr.open( "PUT", url );
xhr.setRequestHeader( "Content-Type", "application/json" );
xhr.onload = () => {
if ( xhr.status === 200 ) {
// reload() uses cache, reload( true ) force no-cache. I reload the page to make "redirects normal effect" of HTML form when submit. You can manipulate DOM instead.
location.reload( true );
} else {
console.log( xhr.status, xhr.responseText );
}
}
xhr.send( body );
}
var deleteMethod = ( event ) => {
event.preventDefault();
var confirm = window.confirm( "Certeza em deletar este conteúdo?" );
if ( confirm ) {
var target = event.target;
while ( target.tagName != "FORM" ) {
target = target.parentElement;
}
var url = target.getAttribute( "action" );
var xhr = new XMLHttpRequest();
xhr.open( "DELETE", url );
xhr.setRequestHeader( "Content-Type", "application/json" );
xhr.onload = () => {
if ( xhr.status === 200 ) {
location.reload( true );
console.log( xhr.responseText );
} else {
console.log( xhr.status, xhr.responseText );
}
}
xhr.send();
}
}
</script>
Con estas funciones definidas, agrego un detector de eventos a los botones que realizan la solicitud del método de formulario:
<script>
document.querySelectorAll( "[name=update_data], [name=delete_data]" ).forEach( element => {
var button = element;
var form = element;
while ( form.tagName != "FORM" ) {
form = form.parentElement;
}
var method = form.getAttribute( "method" );
if ( method == "PUT" ) {
button.addEventListener( "click", putMethod );
}
if ( method == "DELETE" ) {
button.addEventListener( "click", deleteMethod );
}
} );
</script>
Y para el botón Eliminar en el formulario PUT:
<script>
document.querySelectorAll( "[name=remove_data]" ).forEach( element => {
var button = element;
button.addEventListener( "click", deleteMethod );
</script>
_ - - - - - - - - - - -
¡Este artículo https://blog.garstasio.com/you-dont-need-jquery/ajax/ me ayuda mucho!
Más allá de esto, puede configurar la función postMethod y getMethod para manejar los métodos de envío POST y GET como desee en lugar del comportamiento predeterminado del navegador. Puede hacer lo que quiera usar location.reload()
, como mostrar un mensaje de cambios exitosos o eliminación exitosa.
= - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = -