Risposte:
I moduli XHTML 1.x supportano solo GET e POST. GET e POST sono gli unici valori consentiti per l'attributo "metodo".
Secondo il codice HTML standard , è possibile non . Gli unici valori validi per l'attributo method sono get
e post
, corrispondenti ai metodi GET e POST HTTP. <form method="put">
non è un codice HTML valido e verrà trattato come <form>
, ovvero invia una richiesta GET.
Al contrario, molti framework utilizzano semplicemente un parametro POST per eseguire il tunneling del metodo HTTP:
<form method="post" ...>
<input type="hidden" name="_method" value="put" />
...
Ovviamente, questo richiede il wrapping sul lato server.
Posso usare il metodo "Put" in formato html per inviare dati dal modulo HTML al server?
Sì, puoi, ma tieni presente che non si tradurrà in un PUT ma in una richiesta GET. Se si utilizza un valore non valido per l' method
attributo del <form>
tag, il browser utilizzerà il valore predefinito get
.
I moduli HTML (fino alla versione HTML 4 (, 5 Draft) e XHTML 1) supportano GET e POST solo come metodi di richiesta HTTP. Per ovviare a questo problema, eseguire il tunneling di altri metodi tramite POST utilizzando un campo modulo nascosto che viene letto dal server e la richiesta inviata di conseguenza. XHTML 2.0 una volta pianificato per supportare GET, POST, PUT e DELETE per i moduli, ma sta andando in XHTML5 di HTML5 , che non prevede di supportare PUT. [aggiorna a]
In alternativa puoi offrire un modulo, ma invece di inviarlo, crea ed esegui XMLHttpRequest usando il metodo PUT con JavaScript.
PUT /resource
.
HttpRequest.getParameterMap()
non sono stati restituiti parametri del modulo.
_method
soluzione al campo nascosto
La seguente semplice tecnica viene utilizzata da alcuni framework Web:
aggiungi un _method
parametro nascosto a qualsiasi modulo che non sia GET o POST:
<input type="hidden" name="_method" value="PUT">
Questo può essere fatto automaticamente nei framework tramite il metodo helper di creazione HTML.
correggere il metodo del modulo effettivo su POST ( <form method="post"
)
si elabora _method
sul server e fa esattamente come se quel metodo fosse stato inviato al posto del POST effettivo
Puoi farlo in:
form_tag
@method("PATCH")
Razionale / storia del perché non è possibile in puro HTML: /software/114156/why-there-are-no-put-and-delete-methods-in-html-forms
@method("PATCH")
POST
e non quello di cui si ha effettivamente bisogno.
Sfortunatamente, i browser moderni non forniscono supporto nativo per le richieste HTTP PUT. Per aggirare questa limitazione, assicurarsi che l'attributo del metodo del modulo HTML sia "post", quindi aggiungere un parametro di sostituzione del metodo al modulo HTML in questo modo:
<input type="hidden" name="_METHOD" value="PUT"/>
Per testare le tue richieste puoi utilizzare "Postman" un'estensione di Google Chrome
Per impostare i metodi PUT e DELETE eseguo come segue:
<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>
Quindi JS agisce per eseguire i metodi desiderati:
<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 queste funzioni definite, aggiungo un listener di eventi ai pulsanti che richiedono il metodo del modulo:
<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>
E per il pulsante Rimuovi sul modulo PUT:
<script>
document.querySelectorAll( "[name=remove_data]" ).forEach( element => {
var button = element;
button.addEventListener( "click", deleteMethod );
</script>
_ - - - - - - - - - - -
Questo articolo https://blog.garstasio.com/you-dont-need-jquery/ajax/ mi aiuta molto!
Oltre a ciò, puoi impostare la funzione postMethod e getMethod per gestire i metodi di invio POST e GET come preferisci invece il comportamento predefinito del browser. Puoi fare quello che vuoi invece usare location.reload()
, come mostrare il messaggio di modifiche riuscite o cancellazione riuscita.
= - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = - = -