Usando el método PUT en formato HTML

¿Puedo usar un método PUT en un formulario HTML para enviar datos desde el formulario a un servidor?

preguntado el 08 de noviembre de 11 a las 16:11

9 Respuestas

Según la Estándar HTML, puede no. Los únicos valores válidos para el atributo de método son get y post, correspondiente a los métodos HTTP GET y POST. <form method="put"> es HTML inválido y será tratado como <form>, es decir, envíe 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 desenvolvimiento del lado del servidor.

Respondido el 11 de diciembre de 18 a las 22:12

Ha estado vinculando un borrador, no un estándar final. Solo notando que las versiones HTML estables tampoco lo ofrecen. - hakre

@hakre HTML5 ya es el estándar de facto y probablemente evolucionará con el tiempo. Lo que el W3C llama "Borrador" es un documento desarrollado durante al menos 3 años con el aporte de los proveedores de navegadores con más de> 99%, y ya ha sido implementado (al menos cuando se trata de esta y la mayoría de las secciones no esotéricas) por todos ellos para siempre. Pero solo para quisquillosos, aquí está la definición equivalente en HTML 4.01 (una solicitud técnica en los términos del W3C). - Phihag

Por favor, no te ofendas, ya escribí que es solo una nota y que las otras versiones HTML tampoco lo ofrecen (con una ligera excepción de XHTML 2, pero ahora es un borrador obsoleto). - hakre

@hakre Tenga la seguridad de que no estoy ofendido en absoluto. Quitando el quisquilloso, debo comentar que XHTML técnicamente no es HTML, aunque uno puede encontrar una o dos similitudes;) - Phihag

Los formularios XHTML 1.x solo admiten GET y POST. GET y POST son los únicos valores permitidos para el atributo "método".

Respondido el 02 de Septiembre de 14 a las 11:09

XHTML está algo desactualizado. Aún así, parece que los mismos dos valores son válidos en html5 developer.mozilla.org/en-US/docs/Web/HTML/Element/… - Jakubiszon

¿Puedo usar el método "Poner" en un formulario html para enviar datos desde un formulario HTML al servidor?

Sí, puede, pero tenga en cuenta que no resultará en una solicitud PUT sino en una solicitud GET. Si utiliza un valor no válido para el method atributo de la <form> etiqueta, el navegador utilizará el valor predeterminado get.

Los formularios HTML (hasta HTML versión 4 (, 5 Borrador) y XHTML 1) solo admiten GET y POST como métodos de solicitud HTTP. Una solución para esto es tunelizar otros métodos a través de POST utilizando un campo de formulario oculto que es leído por el servidor y la solicitud se envía en consecuencia. XHTML 2.0 una vez planeado para admitir GET, POST, PUT y DELETE para formularios, pero está entrando en XHTML5 of HTML5, que no tiene previsto admitir PUT. [actualización para]

Alternativamente, puede ofrecer un formulario, pero en lugar de enviarlo, cree y active una XMLHttpRequest utilizando el método PUT con JavaScript.

contestado el 23 de mayo de 17 a las 14:05

Una solicitud AJAX no puede reemplazar completamente una solicitud de formulario porque una solicitud de formulario redirige al usuario al recurso dado. Por ejemplo, en este momento no hay forma de mostrar en el navegador la página de la ruta. PUT /resource. - JacopoStanchi

Es una mala idea hacer esto. Los marcos pueden ignorar los parámetros de formulario para los PUT. HTTPServlet de Java parece hacerlo. Tuvimos un error donde HttpRequest.getParameterMap() no devolvió los parámetros del formulario. - DaBlick

@DaBlick: ¿Pero no para XMLHttpRequests? Si es así, confiar en la API de recuperación debería estar más estandarizado. - hakre

_method solución de campo oculto

Algunos frameworks web utilizan la siguiente técnica simple:

  • agregar un oculto _method parámetro 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.

  • corrige el método de formulario real a POST (<form method="post")

  • Procesos _method en el servidor y haga exactamente como si ese método se hubiera enviado en lugar del POST real

Puedes lograr esto en:

  • Rieles: form_tag
  • Laravel: @method("PATCH")

Justificación / historia de por qué no es posible en HTML puro: https://softwareengineering.stackexchange.com/questions/114156/why-there-are-no-put-and-delete-methods-in-html-forms

Respondido el 26 de junio de 19 a las 11:06

Laravel (php) tiene la misma característica al usar @method("PATCH") - santiago arizti

Parece una solución alternativa razonable, pero desafortunada, ya que dificulta la depuración. Por ejemplo, si necesita revisar los registros del servidor o hacer un análisis de red para verificar algunas cosas, no verá la salida correcta, ya que el método HTTP que se usa en los encabezados HTTP sigue siendo POST y no lo que realmente necesitabas. - code_dredd

Desafortunadamente, los navegadores modernos no brindan 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.

Respondido el 03 de diciembre de 16 a las 18:12

Debería funcionar para cualquier método, incluido ELIMINAR Y PARCHE, etc. Tofeeq

para personas que usan laravel

<form method="post" ...>
@csrf
@method('put')
...
</form>

Respondido el 21 de enero de 21 a las 18:01

El código no es la única solución. Por favor, agregue una descripción también. Gracias. - Rayees AC

@Rayees AC, esta es una solución para aquellos que trabajan en el marco de Laravel, para su información. Había escrito eso en negrita en la parte superior de la publicación. De lo contrario, no entendí lo que estás ... CodeToLife

Aunque SO alienta sensiblemente a las personas a no publicar solo respuestas de código, a veces ... como este caso ... es todo lo que necesita. - MemeDesarrollador

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 hacen 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. Puedes hacer lo que quieras en lugar de usar location.reload(), como mostrar mensaje de cambios exitosos o eliminación exitosa.

= - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = -

JSFiddle: https://jsfiddle.net/enriquerene/d6jvw52t/53/

Respondido 21 Feb 19, 03:02

Si está utilizando nodejs, puedes instalar el paquete method-override que le permite hacer esto usando un middleware. Enlace a la documentación: http://expressjs.com/en/resources/middleware/method-override.html

Después de instalar esto, todo lo que tuve que hacer fue lo siguiente:

var methodOverride = require('method-override')
app.use(methodOverride('_method'))

Respondido el 08 de enero de 21 a las 17:01

Escribí un paquete npm llamado 'html-form-enhancer'. Al colocarlo en su fuente HTML, se hace cargo del envío de formularios con métodos además de GET y POST, y también agrega application/json publicación por entregas.

<script type=module" src="html-form-enhancer.js"></script>

<form method="PUT">
...
</form>

Respondido 09 Feb 21, 10:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.