Implémentation cross-browser du pattern "HTTP Streaming" (push) AJAX
Client demande la page web à partir du serveur. Clent puis les demandes pour plus de calculs à faire; server effectue une série de calculs et envoie les résultats partiels dès qu'ils sont disponibles (format texte, chaque ligne contient des élément complet). Client des mises à jour de la page web (avec JavaScript et DOM) en utilisant l'information fournie par le serveur.
Cela semble correspondre à Streaming HTTP (actuel version) modèle de Ajaxpatterns site.
La question est de savoir comment faire en cross-browser (navigateur agnostique), de préférence sans utiliser de JavaScript, ou en utilisant un léger framework comme jQuery.
Le problème commence avec la génération de XMLHttpRequest dans les navigateurs de la mode, mais je pense que le point principal est que tous les navigateurs n'implémentent correctement onreadystatechange
de XMLHttpRequest; pas tous les navigateurs appel onreadystatechange
événement sur chaque serveur flush (BTW. comment faire pour forcer le serveur de chasse à partir de l'intérieur de scripts CGI (Perl)?). Exemple de code sur Ajaxpatterns traite avec cela à l'aide de la minuterie; dois-je déposer la minuterie solution si je détecte une réponse partielle à partir de onreadystatechange
?
Ajouté 11-08-2009
Solution actuelle:
J'ai utiliser la fonction suivante pour créer de l'objet 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;
}
Si je devais utiliser certains (de préférence la lumière-poids) framework JavaScript comme jQuery, j'aimerais avoir de secours si l'utilisateur choisit de ne pas installer jQuery.
J'utilise le code suivant pour démarrer AJAX; setInterval
est utilisé parce que certains navigateurs appel onreadystatechange
seulement après que le serveur ferme la connexion (ce qui peut prendre aussi longtemps que des dizaines de secondes), et non pas dès que le serveur efface les données (autour de chaque seconde ou plus souvent).
function startProcess(dataUrl) {
http = createRequestObject();
http.open('get', dataUrl);
http.onreadystatechange = handleResponse;
http.send(null);
pollTimer = setInterval(handleResponse, 1000);
}
La handleResponse
fonction est plus compliqué, mais le dessin ressemble à celui-ci. Peut-il faire mieux? Comment cela pourrait être fait en utilisant du JavaScript léger cadre (comme 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;
}
source d'informationauteur Jakub Narębski
Vous devez vous connecter pour publier un commentaire.
La solution que vous avez associé n'est pas AJAX à tous, en fait. Ils l'appellent le Streaming HTTP, mais c'est essentiellement juste le temps d'interrogation.
Dans l'exemple qu'ils le lien, vous pouvez voir par vous-même très facilement avec firebug. Tourner sur le Net panneau - il n'y a pas XHR entrées, mais il faut juste un poil plus de 10 secondes pour charger la page d'origine. C'est parce qu'ils sont à l'aide de PHP en coulisses pour retarder la sortie de l'HTML. C'est l'essence même de l'interrogation - le HTTP connexion reste ouverte, et le périodique HTML renvoyée est des commandes javascript.
Vous pouvez opter pour faire le scrutin complètement sur le côté client, si, avec setTimeout() ou la fonction setInterval()
JQuery exemple
Je voudrais prendre un coup d'oeil à mis en orbite
Ils utilisent plusieurs comète de transport la mise en œuvre de la choisir en fonction de la configuration et de la détection de browser.
Voir http://orbited.org/svn/orbited/trunk/daemon/orbited/static/Orbited.js
et recherchez "mis en orbite.CometTransports"
Certaines des différents transports doit être compensée par le backend de mise en œuvre, ont donc un coup d'oeil sur le côté serveur pour tourne en rond aussi.