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 onreadystatechangede 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