2010-11-08 37 views
5

Je viens de commencer à apprendre node.js. Je exemple suivant (serveur):node.js + connecte erreur 404


var app = require("express").createServer(); 
app.listen(80); 

function fail(req, res, next) { setTimeout(next, 10); } 
function success() { 
    return function(req, res, next) { setTimeout(next, 10); }; 
} 
app.get("/success0", success(), function(req, res, next) { res.send("0"); }); 
app.get("/success1", success(), function(req, res, next) { res.send("1"); }); 
app.get("/fail0", fail, function(req, res, next) { res.send("0"); }); 
app.get("/fail1", fail, function(req, res, next) { res.send("1"); }); 

Si j'appelle/fail0 et/fail1 en même temps, l'un d'entre eux réussiront et l'autre échoue avec erreur 404. call/success0 et success1 fonctionnent cependant. Quelqu'un peut-il m'éclairer pourquoi l'un travaille et l'autre non? Ci-dessous mon client de test:


var http = require("http"); 
var sys = require("sys"); 

for(var i = 0; i < 10; i++) { 
    var io = http.createClient(80, "localhost"); 
    var request = io.request("GET", "/fail" + (i%2), {host:"localhost"}); 
    request.on("response", function(response) { 
     var body = ""; 
     response.on("data", function(data) { body += data; }); 
     response.on("end", function() { 
      sys.puts(response.statusCode + ":" + body); 
     }); 
    }).end(); 
} 

en cours d'exécution au-dessus des retours clients:

 
404:Cannot GET /fail0 
200:1 
404:Cannot GET /fail0 
200:1 
404:Cannot GET /fail0 
200:1 
404:Cannot GET /fail0 
200:1 
404:Cannot GET /fail0 
200:1 
+1

Problème intrigant. Je peux reproduire ceci ici mais je ne suis pas sûr de savoir comment le réparer. Cela semble dépendre de la réutilisation de 'fail'. Si vous clonez 'fail' dans deux fonctions' fail0' et 'fail1', cela fonctionne correctement. Doit être quelque chose à faire avec la logique de routeur ou de middleware d'Express ou Connect, mais je ne peux pas voir ce que c'est. – RandomEtc

Répondre

1

Voici une explication de ce bug (et un pointeur vers une solution suit ci-dessous).

La raison est que la logique de routage de la bibliothèque Connect stocke l'état (l'index de l'itinéraire actuel) en tant que propriété dans le rappel de fonction. Dans votre cas de test, lorsque le rappel est enregistré pour la deuxième route, '/ fail1', celui-ci remplace l'état défini par l'itinéraire pour '/ fail0'. Une requête entrante pour fail0 échoue donc.

Ce bug a été signalé sur la liste de diffusion express dans this thread.

Un correctif a été validé dans this fork.