Sunday, October 28, 2007

Ajax: simultaneous asynchronous requests

. Sunday, October 28, 2007

Qualche giorno fa mi son imbattuto in un comportamento alquanto "strano" dell'oggetto XMLHttpRequest che non son ancora riuscito a comprendere del tutto.
In sostanza dovevo ciclare sulle righe di un controllo DataGrid, inizializzare l'oggetto request da inviare al server e ricevere N risposte.
Inizialmente il codice lato client era così strutturato:

<script language="javascript">
var req = null;
function sendData()
{
var data = "";
//Recupero l'url
var url = document.Form1.action;
for (var r = 1; r<5; r++)
{
data
= "id=" + r;
httpRequest(
"POST", url, true, data);
}
}
function httpRequest(reqType, url, asynch, parameter)
{
//Instanzio l'oggetto request
if( window.XMLHttpRequest) //Browser Mozilla
{
req
= new XMLHttpRequest();
}
else if( window.ActiveXObject) //Internet Explorer
{
req
= new ActiveXObject("Msxml2.XMLHTTP");
if( !req)
{
req
= new ActiveXObject("Microsoft.XMLHTTP");
}
}
if(req)
{
if(reqType.toLowerCase() != "post") //Metodo Get
{
initReq(reqType,url,asynch);
}
else
{
if(parameter != null && parameter.length > 0)
{
initReq(reqType,url,asynch,parameter);
}
}
}
}
function initReq( reqType, url, asynch, parameter)
{
try
{
req.onreadystatechange
=function()
{
try
{
if(req.readyState == 4)
{
if(req.status == 200)
{
alert (req.responseText);
}
}
}
catch(error)
{
alert(error);
}
}
req.open(reqType,url,asynch);
if(reqType.toLowerCase() == "post")
{
req.setRequestHeader(
"Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
req.send(parameter);
//Metodo Post
}
else
{
req.send(
null); //Metodo Get
}
}
catch(error)
{
alert( error);
}
}
</script>
Per brevità ho omesso dal metodo sendData il ciclo sulle righe del controllo Datagrid, sostituendo il tutto con un ciclo da 0 a 5.
Da sottolineare come in questo metodo viene preparata la stringa da inviare al server tramite una richiesta HTTP in POST.
Il metodo httpRequest ha la funzione di determinare il tipo dell'oggetto request utilizzato dal browser.
La parte più importante avviene nel metodo initReq.
Qui infatti c'è sia il codice necessario a gestire la risposta del server, sia il codice dell'invio della richiesta in POST.
Nella gestione della risposta viene verificato che la proprietà readyState dell'oggetto request è 4 (elaborazione terminata) e che lo stato della risposta HTTP sia 200.
L'invio della richiesta avviene chiamando la open, preparando la header della richiesta HTTP, ed effettuando l'invio tramite il metodo send.
Lato server, invece ho un metodo che produce N output, in risposta ad ogni richiesta effettuata.
La stranezza è di ottenere, nel caso specifico, 4 risposte identiche. Armato di fiddler mi son accorto che le risposte che ricevo però, sono in realtà diverse:

Per ovviare allo "strano" comportamento, ho modificato lo script, creando l'oggetto request N volte nella funzione createRequest e passato come parametro sia alla funzione httpRequest che di conseguenza alla initReq:
<script language="javascript">
function sendData()
{
var data = "";
//Recupero l'url
var url = document.Form1.action;
for (var r = 1; r<5; r++)
{
data
= "id=" + r;
createRequest(
"POST", url, true, data);
}
}
function createRequest( reqType, url, asynch, parameter)
{
var req = null;
//Instanzio l'oggetto request
if( window.XMLHttpRequest) //Browser Mozilla
{
req
= new XMLHttpRequest();
}
else if( window.ActiveXObject) //Internet Explorer
{
req
= new ActiveXObject("Msxml2.XMLHTTP");
if( !req)
{
req
= new ActiveXObject("Microsoft.XMLHTTP");
}
}
httpRequest( reqType, url, asynch, parameter, req)
}
function httpRequest(reqType, url, asynch, parameter, req)
{
if(req)
{
if(reqType.toLowerCase() != "post") //Metodo Get
{
initReq(reqType,url,asynch, req);
}
else
{
if(parameter != null && parameter.length > 0)
{
initReq(reqType,url,asynch,parameter, req);
}
}
}
}
function initReq( reqType, url, asynch, parameter, req)
{
//Per brevità ho omesso il codice.
}
</script>

0 commenti:

Post a Comment