MICHELEPISANI.IT

Ajax e l'oggetto XMLHttpRequest

Instanziare l'oggetto garantendo la compatibilità su tutti i browser

Codice di istanza e compatibilita cross-browser

Settembre 21
07:232014

La dichiarazione della variabile globale ad inizio codice e la funzione createHMLHttpRequest() rappresentano l'istanza per l'oggetto XMLHttpRequest. Come si può notare all'interno della funzione appena citata avviene una condizione che si basa sul tipo di browser che effettuarà la richiesta al fine di mantenere una compatibilità nel cross-browser anche nel caso di utilizzo da parte di Internet Explorer (che implementa l'XMLHttpRequest come componente ActiveX fino alla versione 6) dovuta all'epoca ad una mancanza di uno standard riconosciuto dal protocollo W3C il quale è attualmente affermato nei browser di oggi.

A scopo si mera curiosità ricordo che il browser della Microsoft, per versioni ancora più obsolete di quella appena citata, necessitava di ulteriori controlli per l'ottenimento di un'istanza dell'oggetto in questione, tuttavia dato che dalla versione 7 è stato integrato come oggetto nativo, risulta superfluo approfondire assegnazioni deprecate (anche in virtù della ricerca che ho effettuato personalmente sui browser più utilizzati al 2014 in Italia e nel Mondo nel quale è dedicata una parte alle verisoni di IE in uso).

Una volta chiamata la funzione che istanzia l'oggetto (createHMLHttpRequest();), nel caso specifico chiamata a sua volta da una funzione denominata MiaFunzione(parametri) (vedere l'articolo precedente per prendere visione del codice in analisi) che può essere invocata per un qualsiasi motivo e che riceve dei parametri in ingresso al fine di svolgere eventuali operazioni, associamo ad una variabile l'url al percorso dove si trova la nostra pagina contenente le operazioni da eseguire lato server che restituirà il codice HTML elaborato da mostrare al client.
Da notare che uno dei parametri in GET che sono passati alla pagina bersaglio è il timestamp, ottenibile in Javascript con la funzione new Date().getTime();. Questo parametro non è obbligatorio e non è nemmeno richiesto, ma per esperienza è molto utile inserire un valore univoco per ciascuna chiamata in quanto gioca un ruolo fondamentale per garantire la compatibilità cross-browser nell'ottenimento della risposta alla chiamata, spiego brevemente il motivo nella curiosità scitta di seguito:


Perchè conviene inserire nei parametri un valore univoco per ciascuna chiamata AJAX?
Il motivo è semplicemente per evitare che la risposta sia in qualche modo influenzata dal caching dei risultati del browser. Questo problema si verifica particolarmente con alcune versioni di Internet Explorer dove, in assenza di un valore univoco per ogni chiamata e avendo eventualmente gli stessi parametri da passare alla pagina, il risultato in risposta potrebbe non essere ricalcolato ma essenso stato inserito nella cache a seguito di una chiamata precedente potrebbe essere ripescato da essa perdendo in taluni casi l'aggiornamento del dato da mostrare a video nonchè l'elaborazione della richiesta.

Un caso pratico in cui mi sono scontrato in passato può essere l'ideale per capire in che situazione il problema potrebbe verificarsi.
Poniamo il caso che ci venga richiesto di programmare effetti ed interazioni lato client per un e-commerce utilizzando solo ed esclusivamente Javascript puro senza avvalersi di librerie esterne quali ad esempio jQuery. Potremmo partire ad esempio dall'implementazione di un'animazione nel momento in cui un prodotto viene aggiunto al carrello con conseguente chiamata Ajax che in background richiama una pagina che agisce sul database e che aggiunge al nostro carrello la quantità del prodotto richiesta.
Una volta messo a punto il sistema lo verifico su tutti i browser e quando è il turno di IExplorer mi rendo conto che cliccando sul bottone per aggiungere al carrello una quantità pari ad 1 del prodotto desiderato tutto fila liscio, ma quando vado a cliccare nuovamente sul bottone per aggiungere la stessa quantità dello stesso prodotto arrivano subito i problemi.
Evito di riportare del codice, che sarebbe solo di intralcio, e cercherò di spiegare a parole quello che succede. Il browser ricevendo la prima chiamata alla pagina "add_to_basket.asp" tramite Ajax e passando come parametri (per semplificare) l'id del carrello, l'id del prodotto e la quantità 1, eseguirà le opportune operazioni di aggiornamento del carrello e restituirà a video il valore 1 nel contenitore dedicato al totale dei prodotti presenti nel carrello stesso da mostrare all'utente; alla seconda chiamata, il browser andrà normalmente a ricercare se nella cache esistono eventuali pagine (risultati) già richiesti in precedenza, ed essendo la chiamata in questione rivolta alla stessa pagina di prima e con gli stessi parametri non percepirò nessuna variazione a video sul totale dei prodotti senza contare che nemmeno il database verrà aggiornato e questo perchè avendo trovato una corripondenza in cache viene evitato di rieseguire calcoli, superflui e apparentemente uguali, fornendo direttamente in risposta quella ottenuta poco prima, ma in questo caso di superfluo c'è ben poco anzi c'è proprio il rischio che la conversione dell'ordine da parte dell'acquirente possa essere compromossa e l'utente potrebbe abbandonare il carrello.

Soluzione
Tra le varie soluzioni che possono esserci, non tutte completamente efficaci, quella che a mio avviso è la più affermata prevede l'inserimento di un parametro univoco ad ogni chiamata. Abbiamo già visto allo scopo l'inserimento di un parametro timestamp ma può essere sufficiente anche una stringa random (per chi può interessare ho dedicato un articolo su come "Generare una stringa random in Javascript"). In questo modo il browser non troverà mai una corrispondenza netta nella cache, dato che almeno un valore nei parametri sarà sicuramente sempre diverso da un altro di una chiamata effettuata in precedenza, con la conseguenza che il codice all'interno della pagina bersaglio verrà eseguito ogni volta, aggiornando il database e restituendo a video i valori corretti.


Chiusa questa parentesi, andiamo ad analizza nel prossimo articolo i metodi, i parametri e le proprietà implicate nel corso di una chiamata asincrona.

Tags
Condividi

Autore

Michele Pisani

Michele Pisani

Ho uno spiccato orientamento al problem-solving, se è troppo facile non mi diverto :)
Credo nella volontà e nel cambiamento perchè hanno fatto della mia passione il mio pane quotidiano.
Se devo descrivermi con una sola parola direi... "Concretezza", la mia stretta di mano è una garanzia.

0 Commenti

Non ci sono commenti

Nessuno ha ancora commentato questo articolo, fallo tu per primo!

Scrivi un Commento

Scrivi un Commento

Il tuo indirizzo email non sarà pubblicato.
I campi contrassegnati da un * sono obbligatori

Articoli e Argomenti correlati

Categorie popolari

Iscriviti alla mia newsletter

La tua e-mail con me sarà al sicuro.
Non fornirò mai le tue informazioni a nessuno!

Ultimi commenti

Michele Pisani

Grazie Paolo,
spero possa tornarti utile per i tuoi scopi.

Paolo

salve,mi interessa il progetto sensore gas ,per applicazioni in agricoltura.Vedremo gli …

Michele Pisani

Ciao Rossana,
strano problema, una domanda: continui a visualizzare entrambe le pagine o una …

Rossana

Ciao Michele, il mio problema è che Facebook non mi risponde. Mi è successo tre volte: faccio …