AJAX – Inviare dati via POST

Proseguendo sulla scia di ieri, vediamo come gestire via AJAX l’invio di dati via form. AJAX si rivela utilissimo per questo tipo di operazioni. Pensate ad una pagina piena di form. L’invio dei dati da un singolo form richiede per l’elaborazione la ricarica di tutta la pagina. Invece, utilizzando una richiesta in background, possiamo gestire singole richieste senza che l’utente perda temporaneamente l’accesso alla pagina dei form.

I vantaggi? Enorme usabilità e velocità di gestione di web application complesse, destinate a continue richieste GET e/o POST dell’utente.

Al momento faremo una cosa semplice, giusto per capire come gestire la cosa. Più in là vedremo come trattare meglio i dati inviati.

Come prima cosa di serve un form. Ecco il form semplice semplice, con codice molto simile a quello che troviamo in vari blog nella sezione dedicata ai commenti.

<form method="post" action="getform.php" onsubmit="InviaDati(); return false;">
<label>Nick</label>: <input type="text" name="nick"><br />
<label>Email</label>: <input type="text" name="email"><br />
<label>Link</label>: <input type="text" name="link"><br />
<input type="submit" name="submit" value="Invia Dati" />
</form>

Cominciamo subito a vedere qualcosa di interessante. In primis il form verrà trattato dalla funzione InviaDati() e successivamente stoppato nel successivo loading dal "return false;" inserito subito dopo. Questo mi permette di inserire un action diverso dal solito "javascritp:void(0)".

Non sono sicuro che il client abbia javascript abilitato nel browser e non voglio provocare mal funzionamenti del form, che in caso di uso impossibile di AJAX verrà gestito dal file "getform.php" con i metodi soliti.

Sta in questo tipo di accorgimenti il concetto di degradabilità di cui si è già parlato qualche post fa.

[MORE]
Prepariamo i dato per l’invio.

La prima cosa da fare è creare una stringa di dati da poter inviare facilmente ed in modo logico allo script che si occuperà di trattare i dati in background.

Possiamo pensare ad una funzione del genere.

function PreparaDati(){
  stringa = "";
  var form = document.forms[0];
  var numeroElementi = form.elements.length;
 
  for(var i = 0; i < numeroElementi; i++){
    if(i < numeroElementi-1){
      stringa += form.elements[i].name+"="+encodeURIComponent(form.elements[i].value)+"&";
    }else{
      stringa += form.elements[i].name+"="+encodeURIComponent(form.elements[i].value);
    } 
  }
}

La funzione creerà una variabile stringa di questo tipo:

nick=valorenick&email=valoreemail&link=valorelink&submit=Invia%20Dati

Inviamo i dati.
Vi ricordate la funzione AJAXReq vista nel post precedente? Vediamola di nuovo. Anche perchè la useremo anche qui:

function AJAXReq(method,url,bool){
  if(window.XMLHttpRequest){
    myReq = new XMLHttpRequest();
  } else
 
  if(window.ActiveXObject){
    myReq = new ActiveXObject("Microsoft.XMLHTTP");
   
    if(!myReq){
      myReq = new ActiveXObject("Msxml2.XMLHTTP");
    }
  }
 
  if(myReq){
    execfunc(method,url,bool);
  }else{
    alert("Impossibilitati ad usare AJAX");
  }
}

Nel nostro handler, se tutto va bene facciamo eseguire la funzione "execfunc()". E’ questa che invierà la stringa. Ed allora dobbiamo pensare alla funzione in modo tale che possa inviare in POST la stringa "stringa".

function execfunc(method,url,bool){
  myReq.onreadystatechange = handleResponse;
  myReq.open(method,url,bool);
  myReq.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
  myReq.send(stringa);
}

Noterete l’utilizzo della proprità "setRequestHeader". Propria di XMLHttpRequest, è utile per settare un header di output. Difatti con myReq.send(stringa) inviamo la stringa impostata dalla funzione PreparaDati(), ma prima diciamo alla pagina di destinazione di ricevere questi valori come dati POST.

Avviamo il tutto.

Una volta che è tutto pronto. Possiamo formalizzare la funzione InviaDati() nel seguente modo.

function InviaDati(){
  PreparaDati();
  AJAXReq("POST","getform.php",true);
}

Niente di più facile. Prepariamo i dati e dopo avviamo la richiesta AJAX che in questo caso invierà i dati via POST al file getform.php.

All’interno di questo file potrei scrivere qualsiasi tipo di codice PHP per manipolare i dati ricevuti via POST. In questo caso ho deciso di stampare l’array di debug dei dati in post.

<?php
  print_r($_POST);
?>

E per mostrare il risultato mi creo una funzione handleResponse() adeguata. Niente di che, il solito alert al momento πŸ™‚

function handleResponse(){
  if(myReq.readyState == 4){
    if(myReq.status == 200){
      alert(myReq.responseText);
    }else{
      alert("Niente da fare, AJAX non funziona :(");
    }
  }
}

Come sempre e a vostra disposizione un esempio pratico on line. Per chi fosse interessato, il codice javascript completo è in chiaro e facilmente prelevabile.

36 thoughts on “AJAX – Inviare dati via POST”

  1. Vediamo se ho capito bene. Nell'esempio che vediamo qua i dati vengono inviati a getform.php per essere passati all'array. Mentre se volessi passarli all'interno di un db, in getform.php (.asp nel mio caso) ci devo inserire i comandi SQL per l'inserimento nel db.

    O no? :-/

  2. Esatto Gionni!

    In linea generale nel file di destinazione della chiamata in background dovrai inserire tutte le funzioni per la manipolazione dei dati:

    – validazione dati

    – modifica

    – inserimento in db

    Nell'esempio di sopra io faccio la cosa più facile. Mostro l'array $_POST per far vedere che i dati sono stati correttamente passati con il metodo post. Ma si potrebbe fare la qualsiasi cosa πŸ™‚

    Se scarichi la mia versione di dblog, postata qualche articolo fa, dai uno sguardo ai file che si occupano dell'inserimento dei commenti in ajax.

  3. La cosa che un po' mi scoccia è dover creare tutti 'sti file .js, anche se mi rendo conto che rende più semplice ed ordinato il tutto. Per il blog mi accontento di quello che c'è. Me lo studio per altri progetti.

  4. La cosa che un po' mi scoccia è dover creare tutti 'sti file .js, anche se mi rendo conto che rende più semplice ed ordinato il tutto. Per il blog mi accontento di quello che c'è. Me lo studio per altri progetti.

  5. Mm ma cosi si collega alla pagina getform.php..mi sembra come se lo stessi eseguendo in php senza l'aiuto di ajax..se io invece volessi far rimanere tutto in questa pagina e farmi caricare solo la risposta..come è tipico di ajax..

    come si fa??

  6. Puoi far gestire la risposta allo stesso file che invia la richiesta, richiamandolo in self. Oppure fare tutto via javascript, ma scusa, cosa non è tipico di ajax in questo modo?

  7. No scusa,non volevo dire che in qst caso non c'è qlcs tipico di ajax,è ke ajax permette di caricare solo la parte che ti interessa..ed era quello che im interessava piuttosto che andare a finre nella pagina getpost.

    Stavo cercando da un po di giorni qlcs simile a quello che hai fatto tu sopra..e questo è uno dei pochi siti che mettono una soluzione interessante..sebbene non proprio quello che volevo fare io..

    io avrei un file php che prende dal database delle tuple e le inserisce in una tabella come checkbox, l'utente le seleziona,e fa submit(per eliminarle).

    Con ajax volevo che dopo il submit mi venissero fuori subito le tuple eliminate invece che aspettare il caricamento di tutta la pagina..mi sapresti dire come si fa..??

  8. @ hab: se leggi il mio codice nella pagina d'esempio, considera che l'action impostato è lì solo per degradabilità.

    AJAX non funziona se il client ha javascript disabilitato.

    Se è abilitato l'action del form non avrà nessun effetto, azionandosi la direttiva onsubmit con relativo return false; che blocca l'action.

    Puoi usare la stessa tecnica che uso io. Nella funzione di javascript manda in loading asincronico in file che si occupa di cancellare dal db i dati. Allo stesso tempo crea con i dati inviati via post un array adeguato per essere visualizzato.

    Purtroppo per essere più specifico dovrei vedere i file.

    Per far comparire il testo, usa innerHTML come spiegato qui: http://www.davidonzo.com/post/610/ajax–gestione-della-risposta-http/

  9. ciao davidonzo, se volessi vedere i risultati invece che come avviso di javascript, in una determinata pagina, come dovrei usare.

    Per ora sono riuscito a visualizzarela con

    document.getElementById('myform').innerHtml = result

    questo mi rimuoveva il form e mi inseriva i suoi risultati..ora mi servirebbe vederlo in una pagina come posso fare<??

    grazie

  10. @ fred: puoi farlo usando AJAX e facendo comparire il risultato della query in un id diverso da myform.

    Crea un elemento div vuoto dove preferisci compaiano i risultati e dagli come id "result".

    A quel punto usando document.getElementById('result').innerHTML = result visualizzerai il tutto nel div vuoto, senza perdere la visualizzazione della form.

    Se non vuoi usare AJAX invece cancella l'onsubmit del tag form ed allora processerai direttamente il file getform.php andandolo ad aprire col browser.

  11. Ciao davidonzo, i tuoi script son sempre utilissimi e ti faccio i miei complimenti.

    Vorrei solo chiederti una informazione su un problema che riscontro quando invio i dati da un form:

    se scrivo per esempio:

    olà

    mi stampa a schermo:

    olÃ

    questo vuol dire che la codifica in UTF-8 che gli suggeriamo non funziona…saprei consigliarmi o aiutarmi per risolvere questo problema?

  12. Ciao A35G e grazie per i complimenti πŸ™‚

    Il problema non deriva dallo script, ma dal charset del documento che visualizza la risposta del server.

    Se questo è in iso-8859-1, allora è normale avere problemi di visualizzazione.

    Come puoi testare tu stesso in questo blog (usa l'anteprima di un commento) le lettere accentate vengono visualizzate bene perchè inviate in UTF-8 ad un documento (qualsiasi pagina di questo blog) che usa il medesimo charset.

  13. Il bello è che il charset della pagina è in UTF-8, il browser è in UTF-8, il DB è in UTF-8 ma le lettere le vedo male o.o

  14. Risolto πŸ™‚

    htmlentities() di PHP, di default, usa la codifica ISO-8859-1.

    Risolto con htmlentities ( $variabile, ENT_QUOTES, "UTF-8" );

  15. Ciao…:)

    Ho letto il tuo articolo, lo trovo molto interessante. Io volevo usare il metodo POST per inviare dati, abbastanza grandi, attraverso una richiesta asincrona, il problema è che nei dati che invio compaiono spesso e volentieri delle "&" e quando il metodo send vede una "&" associa una nuova coppia chiave valore, tagliando di netto il resto del messaggio, tu hai qualche soluzione a questo problema?..:)..grazie!..;-)

  16. Ciao Flavio.

    Devi cercare di trattare le & come &amp;. In questo modo saranno considerate puro testo. Esattamente come avviene per l'invio via ajax di questo commento.

  17. mmmm…credo di aver afferrato il concetto…

    Solo che non ho idea dell'implementazione di quello che tu mi dici.

    Avresti voglia, per piacere, di darmi delle indicazioni sul dove trovare del codice che faccia questo?

    Mi basta l'implementazione della &…

    Grazie mille..:)

    Se vuoi t allungo la mia mail così ne parliamo in privato.

  18. Non so chi siete ma mi avete risolto un problema.
    La descrizione è chiarissima e i successivi post sono di aiuto.
    Grazie mille

  19. ciao davionzo,
    volevo sapere una cosa ma usare troppo javascript non è fonte di attacco di hacker ?

  20. Ciao SolidSnake4,

    Non è la quantità del codice che determina la vulnerabilità o meno di un applicativo, ma come viene scritto il codice. E proprio javascript, considerando che stiamo parlando di un linguaggio client side, da meno problemi di vulnerabilità ad un sito di quanto ne può dare uno script asp/php/cfm/rb scritto in malo modo.

    E' ovvio che più codice eseguibile contiene un web, maggiore è la possibilità che ci siano falle e/o bug, ma questo è da leggere solo come dato probabilistico.

  21. Ciao davidonzo,
    a me, più che altro, servirebbe uno script tipo questo in cui ho un serie di checkboxes, la cui valiudazione o meno, determina la visualizzazione degli elementi di un elenco.
    Mi spiego meglio:

    [ ]Agriturismi
    [X]Bed and Breakfast
    [X]Case vacanze

    <ul>
    <li><h2>STRUTTURA 1</h2>
    <p>tipologia struttura: bed and breackfast</p></li>
    <li><h2>STRUTTURA 2</h2>
    <p>tipologia struttura: bed and breackfast</p></li>
    <li><h2>STRUTTURA 3</h2>
    <p>tipologia struttura: bed and breackfast</p></li>
    <li><h2>STRUTTURA 4</h2>
    <p>tipologia struttura: case vacanze</p></li>
    </ul>

    Vorrei fare in modo che questo script funzioni senza che io clicki su nessun submit, sive che la lista mi s'aggiorni in automatico nel momento in cui io spunto le mie checkboxes.
    Puoi aiutarmi, per favore?

    Grazie in anticipo
    P.S.: sono un neofita AJAX, quindi non ti stupire della possibile idiozia della richiesta e soprattutto, dai per scontato meno cose possibili.

  22. Ottimo esempio di post con Ajax,
    io avevo scritto una funzione per la preparazione della stringa da passare via post che prende in input il nome della form. Utile nel caso vi siano più form nella pagina. E soprattutto verifica il tipo del campo per leggere anche i valori dei campi select.
    Spero possa essere utile:

    function formdata(form_id){
    var postdata = "";
    var form = document.getElementById(form_id);
    var nElements = form.elements.length;

    for(var i = 0; i < nElements; i++){
    switch(form.elements[i].type){
    case "select":
    postdata += form.elements[i].name+"="+encodeURIComponent(form.elements[i].options[form.elements[i].selectedIndex].value);
    break;
    default:
    postdata += form.elements[i].name+"="+encodeURIComponent(form.elements[i].value);
    break;
    }
    if(i < nElements-1){ postdata+="&"; }
    } return postdata;
    }

    Un saluto a davidonzo, trovo il tuo sito molto utile

    Mauro

  23. Mi spieghi come nel tuo esempio si può passare la variabile stringa di PreparaDati() alla funzione execfunc()? grazie

  24. sono un neofita AJAX, quindi non ti stupire della possibile idiozia della richiesta e soprattutto, dai per scontato meno cose possibili.

Comments are closed.