Verwendung der PUT-Methode in HTML-Form


174

Kann ich eine PUT-Methode in einem HTML-Formular verwenden, um Daten aus dem Formular an einen Server zu senden?

Antworten:



194

Nach dem HTML-Standard können Sie nicht . Die einzigen gültigen Werte für das Methodenattribut sind getund post, entsprechend den HTTP-Methoden GET und POST. <form method="put">ist ungültiges HTML und wird wie behandelt behandelt <form>, dh eine GET-Anfrage senden.

Stattdessen verwenden viele Frameworks einfach einen POST-Parameter, um die HTTP-Methode zu tunneln:

<form method="post" ...>
  <input type="hidden" name="_method" value="put" />
...

Dies erfordert natürlich ein serverseitiges Auspacken.


3
Sie haben einen Entwurf verknüpft, keinen endgültigen Standard. Nur zu beachten, die stabilen HTML-Versionen bieten es auch nicht an.
hakre

13
@hakre HTML5 ist bereits der De-facto-Standard und wird sich wahrscheinlich im Laufe der Zeit weiterentwickeln. Was das W3C "Draft" nennt, ist eine Dokumentation, die über mindestens 3 Jahre unter Einbeziehung von Browser-Anbietern mit mehr als> 99% entwickelt wurde und bereits implementiert wurde (zumindest in Bezug auf diesen und die meisten nicht-esoterischen Abschnitte) von alle für immer. Aber nur für Nitpicker, hier ist die äquivalente Definition in HTML 4.01 (eine technische Anfrage in den Begriffen des W3C).
Phihag

Bitte fühlen Sie sich nicht beleidigt, ich habe bereits geschrieben, dass es nur eine Notiz ist und dass die anderen HTML-Versionen es auch nicht anbieten (mit einer kleinen Ausnahme von XHTML 2, aber das ist jetzt ein veralteter Entwurf).
hakre

1
@akre Seien Sie versichert, ich bin überhaupt nicht beleidigt. Wenn ich den Nitpicker auswähle, muss ich kommentieren, dass XHTML technisch gesehen kein HTML ist, obwohl man vielleicht ein oder zwei Ähnlichkeiten findet;)
Phihag

44

Kann ich die "Put" -Methode in HTML-Form verwenden, um Daten von HTML Form an den Server zu senden?

Ja, das können Sie, aber denken Sie daran, dass dies nicht zu einem PUT, sondern zu einer GET-Anforderung führt. Wenn Sie einen ungültigen Wert für das methodAttribut des <form>Tags verwenden, verwendet der Browser den Standardwert get.

HTML-Formulare (bis zu HTML Version 4 (, 5 Draft) und XHTML 1) unterstützen nur GET und POST als HTTP-Anforderungsmethoden. Eine Problemumgehung hierfür besteht darin, andere Methoden durch POST zu tunneln, indem ein ausgeblendetes Formularfeld verwendet wird, das vom Server gelesen und die Anforderung entsprechend gesendet wird. XHTML 2.0 plante einst die Unterstützung von GET, POST, PUT und DELETE für Formulare, geht jedoch in XHTML5 von HTML5 über , das PUT nicht unterstützen soll. [aktualisieren zu]

Sie können alternativ ein Formular anbieten, aber anstatt es zu senden, erstellen und feuern Sie eine XMLHttpRequest mithilfe der PUT-Methode mit JavaScript.



Eine AJAX-Anforderung kann eine Formularanforderung nicht vollständig ersetzen, da eine Formularanforderung den Benutzer zur angegebenen Ressource umleitet. Zum Beispiel gibt es derzeit keine Möglichkeit, die Seite der Route im Browser anzuzeigen PUT /resource.
JacopoStanchi

Es ist eine schlechte Idee, dies zu tun. Frameworks können Formularparameter für PUTs ignorieren. Javas HTTPServlet scheint zu. Wir hatten einen Fehler, bei dem HttpRequest.getParameterMap()keine Formularparameter zurückgegeben wurden.
DaBlick

@DaBlick: Aber nicht für XMLHttpRequests? In diesem Fall sollte die Verwendung der Abruf-API standardisierter sein.
hakre

26

_method Problemumgehung für versteckte Felder

Die folgende einfache Technik wird von einigen Web-Frameworks verwendet:

  • Fügen Sie _methodjedem Formular, das nicht GET oder POST ist , einen versteckten Parameter hinzu:

    <input type="hidden" name="_method" value="PUT">

    Dies kann in Frameworks automatisch über die Hilfsmethode zur HTML-Erstellung erfolgen.

  • Korrigieren Sie die eigentliche Formularmethode auf POST ( <form method="post")

  • Prozesse _methodauf dem Server und tun genau so, als ob diese Methode anstelle des eigentlichen POST gesendet worden wäre

Sie können dies erreichen in:

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

Begründung / Verlauf, warum dies in reinem HTML nicht möglich ist: /software/114156/why-there-are-no-put-and-delete-methods-in-html-forms


Laravel (PHP) hat die gleiche Funktion mit@method("PATCH")
Santiago Arizona

Es scheint eine vernünftige Problemumgehung zu sein, ist aber immer noch unglücklich, da es das Debuggen schwierig macht. Wenn Sie beispielsweise Serverprotokolle durchgehen oder Netzwerkanalysen durchführen müssen, um einige Dinge zu überprüfen, wird die korrekte Ausgabe nicht angezeigt, da die in den HTTP-Headern verwendete HTTP-Methode immer noch POSTnicht die tatsächlich benötigte ist.
Code_Dredd

8

Leider bieten moderne Browser keine native Unterstützung für HTTP-PUT-Anforderungen. Um diese Einschränkung zu umgehen, stellen Sie sicher, dass das Methodenattribut Ihres HTML-Formulars "post" lautet, und fügen Sie Ihrem HTML-Formular einen Parameter zum Überschreiben von Methoden wie folgt hinzu:

<input type="hidden" name="_METHOD" value="PUT"/>

Um Ihre Anfragen zu testen, können Sie "Postman", eine Google Chrome-Erweiterung, verwenden


1
Es sollte für jede Methode funktionieren, einschließlich LÖSCHEN UND PATCH usw.
Tofeeq

1

Um die Methoden PUT und DELETE einzustellen, gehe ich wie folgt vor:

<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>

Dann führt JS die gewünschten Methoden aus:

<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>

Wenn diese Funktionen definiert sind, füge ich den Schaltflächen, die die Formularmethodenanforderung stellen, einen Ereignis-Listener hinzu:

<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>

Und für die Schaltfläche zum Entfernen im PUT-Formular:

<script>
  document.querySelectorAll( "[name=remove_data]" ).forEach( element => {
    var button = element;
    button.addEventListener( "click", deleteMethod );
</script>

_ - - - - - - - - - - - -

Dieser Artikel https://blog.garstasio.com/you-dont-need-jquery/ajax/ hilft mir sehr!

Darüber hinaus können Sie die postMethod-Funktion und getMethod so einstellen, dass POST- und GET-Übermittlungsmethoden nach Ihren Wünschen behandelt werden, anstatt das Standardverhalten des Browsers. Sie können stattdessen tun, was Sie möchten location.reload(), z. B. die Meldung erfolgreicher Änderungen anzeigen oder erfolgreich löschen.

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

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.