HTML biçiminde PUT yöntemini kullanma


175

Formdan bir sunucuya veri göndermek için HTML formunda PUT yöntemini kullanabilir miyim?

Yanıtlar:



194

Göre HTML standardı yapabilirsiniz değildir . Method özniteliği için geçerli olan tek değerler getve post, GET ve POST HTTP yöntemlerine karşılık gelir. <form method="put">geçersiz HTML'dir ve gibi davranılır <form>, yani bir GET isteği gönderin.

Bunun yerine, birçok çerçeve HTTP yöntemini tünellemek için bir POST parametresi kullanır:

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

Tabii ki, bu sunucu tarafı açmayı gerektirir.


3
Son bir standart değil, bir taslağı bağladınız. Sadece dikkat çeken, istikrarlı HTML sürümleri de sunmuyor.
hakre

13
@hakre HTML5 zaten fiili standarttır ve muhtemelen zamanla gelişecektir. W3C'nin "Taslak" olarak adlandırdığı şey, en az 3 yıl içinde>% 99'dan fazla tarayıcı satıcısı girdisi ile geliştirilmiş ve (en azından bu ve çoğu ezoterik olmayan bölümler söz konusu olduğunda) hepsi sonsuza dek. Ancak sadece nitpickers için, HTML 4.01'deki eşdeğer tanım (W3C'nin şartlarına göre Teknik İstek).
phihag

Lütfen rahatsız hissetmeyin, bunun sadece bir not olduğunu ve diğer HTML sürümlerinin de sunmadığını yazdım (XHTML 2'nin hafif bir istisnasıyla, ancak şimdi eski bir taslak).
hakre

1
@hakre Hiç rahatsız olmadığımdan emin olabilirsiniz. Nitpicker nitpicking, XHTML teknik olarak HTML değil, bir veya iki benzerlik bulabiliriz yorum
yapmalıyım

44

HTML Formundan sunucuya veri göndermek için "Put" yöntemini html biçiminde kullanabilir miyim?

Evet yapabilirsiniz, ancak bunun bir PUT değil bir GET isteğiyle sonuçlanacağını unutmayın. Etiketin methodözelliği için geçersiz bir değer <form>kullanırsanız, tarayıcı varsayılan değeri kullanır get.

HTML formları (HTML sürüm 4'e kadar (, 5 Taslak) ve XHTML 1) HTTP istek yöntemleri olarak yalnızca GET ve POST'u destekler. Bunun bir çözümü, sunucu tarafından okunan gizli bir form alanı ve buna göre gönderilen istek kullanılarak POST aracılığıyla diğer yöntemleri tünellemektir. XHTML 2.0 desteği GET, POST, PUT planlanan ve formlar için DELETE, ama giriyor kez XHTML5 ait HTML5 desteği PUT değil planını yapar. [güncelleme]

Alternatif olarak bir form sunabilirsiniz, ancak göndermek yerine JavaScript ile PUT yöntemini kullanarak bir XMLHttpRequest oluşturun ve tetikleyin.



Bir form isteği kullanıcıyı verilen kaynağa yönlendirdiği için AJAX isteği bir form isteğinin yerine geçemez. Örneğin, şu anda tarayıcıda rotanın sayfasını göstermenin bir yolu yoktur PUT /resource.
JacopoStanchi

Bunu yapmak kötü bir fikir. Çerçeveler PUT'lar için form parametrelerini yoksayabilir. Java'nın HTTPServlet'i görünüyor. Biz HttpRequest.getParameterMap()form parametreleri döndürmedi bir hata vardı .
DaBlick

@DaBlick: Ama XMLHttpRequests için değil mi? Eğer öyleyse, getirme API'sine güvenmek daha standart hale getirilmelidir.
hakre

27

_method gizli alan geçici çözümü

Aşağıdaki basit teknik birkaç web çerçevesi tarafından kullanılır:

  • _methodGET veya POST olmayan herhangi bir forma gizli bir parametre ekleyin :

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

    Bu, HTML oluşturma yardımcı yöntemi aracılığıyla çerçevelerde otomatik olarak yapılabilir.

  • gerçek form yöntemini POST ( <form method="post") olarak düzeltin

  • _methodsunucudaki işlemleri ve gerçek POST yerine bu yöntem gönderilmiş gibi yapın

Bunu şu şekilde yapabilirsiniz:

  • Raylar: form_tag
  • laravel: @method("PATCH")

Saf HTML'de neden mümkün olmadığının gerekçesi / geçmişi: /software/114156/why-there-are-no-put-and-delete-methods-in-html-forms


Laravel (php) kullanarak aynı özelliğe sahiptir@method("PATCH")
santiago arizti

Hata ayıklamayı zorlaştırdığı için makul bir çözüm gibi görünüyor, ama yine de talihsiz. Örneğin, bazı şeyleri doğrulamak için sunucu günlüklerinden geçmeniz veya ağ analizi yapmanız gerekiyorsa, HTTP üstbilgilerinde kullanılan HTTP yöntemi POSTgerçekte ihtiyaç duyduğunuz şey olmadığı için doğru çıktıyı görmezsiniz .
code_dredd

8

Ne yazık ki, modern tarayıcılar HTTP PUT istekleri için yerel destek sağlamamaktadır. Bu sınırlamaya geçici bir çözüm bulmak için, HTML formunuzun yöntem özelliğinin "yayın" olduğundan emin olun, ardından HTML formunuza aşağıdaki gibi bir yöntem geçersiz kılma parametresi ekleyin:

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

İsteklerinizi test etmek için bir Google Chrome uzantısı olan "Postacı" kullanabilirsiniz


1
DELETE AND PATCH vb. Dahil olmak üzere herhangi bir yöntem için çalışmalıdır
Tofeeq

1

PUT ve DELETE yöntemlerini ayarlamak için aşağıdaki işlemleri gerçekleştiririm:

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

Daha sonra JS, istenen yöntemleri gerçekleştirmek için çalışır:

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

Bu işlevler tanımlandığında, form yöntemi isteğinde bulunan düğmelere bir olay dinleyicisi eklerim:

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

Ve PUT formundaki kaldır düğmesi için:

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

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

Bu makale https://blog.garstasio.com/you-dont-need-jquery/ajax/ bana çok yardımcı oluyor!

Bunun ötesinde, POST ve GET gönderme yöntemlerini tarayıcı varsayılan davranışı gibi işlemek için postMethod işlevini ve getMethod'u ayarlayabilirsiniz. Bunun yerine location.reload(), başarılı değişikliklerin gösterme mesajı veya başarılı silme gibi kullanmak istediğinizi yapabilirsiniz .

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

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.