Pagina Web richiesta client dal server. Clent richiede quindi che vengano eseguiti ulteriori calcoli; server esegue serie di calcoli e invia risultati parziali non appena sono disponibili (formato di testo, ogni riga contiene elementi separati separati). Client aggiorna la pagina web (con JavaScript e DOM) utilizzando le informazioni fornite dal server.Implementazione cross-browser di "HTTP Streaming" (push) Pattern AJAX
Questo sembra adattarsi al modello HTTP Streaming (current) dal sito Ajaxpatterns.
La domanda è come farlo in modalità cross-browser (browser agnostico), preferibilmente senza utilizzare framework JavaScript, o utilizzando un framework leggero come jQuery.
Il problema inizia con la generazione di XMLHttpRequest in modalità cross-browser, ma penso che l'elemento principale sia che non tutti i browser implementano correttamente onreadystatechange
da XMLHttpRequest; non tutti i browser chiamano l'evento onreadystatechange
su ogni server flush (come forzare lo svuotamento del server dallo script CGI (in Perl)?). Il codice di esempio su Ajaxpatterns si occupa di ciò usando il timer; dovrei rilasciare la soluzione timer se rilevo risposta parziale da onreadystatechange
?
Aggiunto 11-08-2009
soluzione attuale:
Io uso la seguente funzione per creare l'oggetto XMLHttpRequest:
function createRequestObject() {
var ro;
if (window.XMLHttpRequest) {
ro = new XMLHttpRequest();
} else {
ro = new ActiveXObject("Microsoft.XMLHTTP");
}
if (!ro)
debug("Couldn't start XMLHttpRequest object");
return ro;
}
Se dovessi usare alcuni (preferibilmente leggero) framework JavaScript come jQuery, mi piacerebbe avere fallback se utente sceglie di non installare jQuery.
Io uso il seguente codice per avviare AJAX; setInterval
viene utilizzato perché alcuni browser chiamano onreadystatechange
solo dopo che il server chiude la connessione (che può richiedere fino a decine di secondi), e non appena il server scarica i dati (circa ogni secondo o più spesso).
function startProcess(dataUrl) {
http = createRequestObject();
http.open('get', dataUrl);
http.onreadystatechange = handleResponse;
http.send(null);
pollTimer = setInterval(handleResponse, 1000);
}
La funzione handleResponse
è quello più complicato, ma il disegno di esso appare come il seguente. Può essere fatto meglio? Come si farebbe usando un leggero framework JavaScript (come jQuery)?
function handleResponse() {
if (http.readyState != 4 && http.readyState != 3)
return;
if (http.readyState == 3 && http.status != 200)
return;
if (http.readyState == 4 && http.status != 200) {
clearInterval(pollTimer);
inProgress = false;
}
// In konqueror http.responseText is sometimes null here...
if (http.responseText === null)
return;
while (prevDataLength != http.responseText.length) {
if (http.readyState == 4 && prevDataLength == http.responseText.length)
break;
prevDataLength = http.responseText.length;
var response = http.responseText.substring(nextLine);
var lines = response.split('\n');
nextLine = nextLine + response.lastIndexOf('\n') + 1;
if (response[response.length-1] != '\n')
lines.pop();
for (var i = 0; i < lines.length; i++) {
// ...
}
}
if (http.readyState == 4 && prevDataLength == http.responseText.length)
clearInterval(pollTimer);
inProgress = false;
}
È necessario aggiungere l'esempio di codice come risposta e contrassegnarlo come corretto! –
"se l'utente decide di non installare jQuery"? – Basic
Ciao, ho appena trovato la soluzione, ma temo che non funzionerà ancora con IE, dal momento che quando cercherete di ottenere il responseText mentre le richieste non sono ancora terminate, otterrete il seguente messaggio: "I dati necessari per completare questa operazione non sono ancora disponibili". –