26 votes

Comment puis-je afficher des données avant de terminer la réponse?

Voici mon extrait de code que j'ai testé dans Chrome 11 et Firefox 4 :

var http = require('http');

http.createServer(function(request, response){
   // Write Headers
   response.writeHead(200);

   // Write Hello World!
   response.write("Hello World!");

   // End Response after 5 seconds
   setTimeout(function(){ 
        response.end(); 
   }, 5000);

}).listen(8000);

Comme vous pouvez le voir, j'ai programmé une temporisation sur response.end() pour tester si response.write est affiché avant response.end. Cependant, dans mon expérience, ce n'est pas le cas.

Existe-t-il un moyen d'afficher les données avant de terminer la réponse, comme l'envoi des données en paquets ?

19voto

gillyb Points 2851

Il y a en fait un moyen de le faire sans définir Content-Type: text/plain et toujours utiliser text/html comme le Content-Type, mais vous devez dire au navigateur de s'attendre à des morceaux de données.

Cela peut être fait facilement comme ceci :

var http = require('http');

http.createServer(function(request, response) {

    response.setHeader('Connection', 'Transfer-Encoding');
    response.setHeader('Content-Type', 'text/html; charset=utf-8');
    response.setHeader('Transfer-Encoding', 'chunked');

    response.write('hello');

    setTimeout(function() {
        response.write(' world!');
        response.end();
    }, 10000);

}).listen(8888);

Cependant, vous devez savoir que jusqu'à ce que response.end() soit appelé, la requête est toujours en cours et bloque d'autres requêtes vers votre serveur nodejs.
Vous pouvez facilement tester cela en ouvrant cette page (localhost:8888) sur deux onglets différents. L'un d'eux attendra 10 secondes, et l'autre n'obtiendra que le début de la réponse une fois que la première réponse se termine (ce qui signifie que vous attendrez 10 secondes pour le début de la réponse et encore 10 secondes jusqu'à la fin de la réponse en utilisant ce code).

Vous pouvez probablement surmonter cet obstacle en exécutant plusieurs processus nodejs et en équilibrant la charge entre eux, mais alors cela commence à devenir beaucoup plus compliqué, et c'est un sujet qui devrait être abordé ailleurs... :)

16voto

Geoff Chappell Points 1786

Si vous modifiez le type de contenu en text/plain -- par exemple :

// Écrire les en-têtes
response.writeHead(200, {'Content-Type': 'text/plain'});

alors Firefox affichera le contenu immédiatement. Chrome semble toujours mettre en mémoire tampon (si vous écrivez beaucoup plus de contenu, Chrome l'affichera immédiatement).

15voto

Vlad Points 1

Si vous voulez afficher du texte brut fragmenté dans Chrome - tout comme ce que Firefox fait par défaut - vous devez utiliser l'en-tête 'X-Content-Type-Options': 'nosniff'. Voir Qu'est-ce que "X-Content-Type-Options=nosniff"?

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {
        'Content-Type': 'text/plain; charset=utf-8',
        'Transfer-Encoding': 'chunked',
        'X-Content-Type-Options': 'nosniff'});
    res.write('Début\n');
    var count = 10;
    var io = setInterval(function() {
        res.write('En train de faire ' + count.toString() + '\n');
        count--;
        if (count === 0) {
            res.end('Terminé\n');
            clearInterval(io);
        }
    }, 1000);
}).listen(8888);

Vous n'avez pas besoin de cette option si votre sortie est text/html.

Solution trouvée à partir de ce défaut de Chrome : Transfer-Encoding chunked not support on text/plain

3voto

Voici les points principaux que vous devez noter :

  • spécifier un jeu de caractères
  • chaque "chunk" sera affiché par le navigateur (du moins, ce que j'ai remarqué dans Chrome) à travers une nouvelle ligne (si le jeu de caractères est text/html)

Comme ceci :

res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.write('a');
setTimeout(function() {
  res.write('b');
  setTimeout(function() {
    res.write('c');
    res.end();
  }, 2000);
}, 2000);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X