2013-01-07 10 views
6

Ich habe eine einfache Knoten-App, die Metriken von Clients schreiben sollte. Clients senden Metriken im JSON-Format, das mit dem zlib-Modul von Python gezippt wurde. Ich versuche, eine Middleware hinzuzufügen, um den Anforderungspost zu entpacken, bevor der Express-BodyParse stattfindet.Entpacken POST Körper mit Knoten + Express

Meine Middle sind einfach die per Express standardmäßig zur Verfügung gestellt diejenigen:

app.configure(function(){ 
    app.set('port', process.env.PORT || 3000); 
    app.set('views', __dirname + '/views'); 
    app.set('view engine', 'jade'); 
    app.use(express.favicon()); 
    app.use(express.logger('dev')); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(express.cookieParser('your secret here')); 
    app.use(express.session()); 
    app.use(app.router); 
    app.use(require('less-middleware')({ src: __dirname + '/public' })); 
    app.use(express.static(path.join(__dirname, 'public'))); 
}); 

Ich habe versucht, eine einfache Middleware hinzufügen, die die Daten bekommt und dann unzips:

app.use(function(req, res, next) { 
    var data = ''; 
    req.addListener("data", function(chunk) { 
     data += chunk; 
    }); 

    req.addListener("end", function() { 
     zlib.inflate(data, function(err, buffer) { 
      if (!err) { 
       req.body = buffer; 
       next(); 
      } else { 
       next(err); 
      } 
     }); 
    }); 
}); 

Das Problem ist mit zlib.inflate bekomme ich diesen Fehler:

Die Daten wurden mit komprimiert python zlib-modul:

zlib.compress(jsonString) 

aber scheint, dass weder entpacken, aufblasen, gunzip funktioniert.

+0

Sind Sie sicher, dass Sie nicht ein „err“ von zlib.unzip erhalten und als Ergebnis Das nächste() wird nicht aufgerufen? Wenn dies der Fall ist, versuchen Sie, die Daten in ein Array zu schalten. Überprüfen Sie diese Antwort http://StackOverflow.com/A/12776856/30763 Darüber hinaus stellen Sie sicher, dass Ihre Middleware vor bodyParser verwendet wird. – Aaron

+0

Diese Antwort ist nicht zum Entpacken einer Anfrage von Knoten und nicht vom Client erledigt? – alex88

+1

@ alex88 In jedem Fall sollten Sie 'next (err)' aufrufen, wenn ein Fehler vorliegt. Ich schlage auch vor, dass Sie auf die 'bodyParser'-Middleware verzichten und' req.body = JSON.parse (buffer) 'direkt ausführen. –

Antwort

12

die Lösung auf meinem eigenen gefunden, war das Problem mit diesem Stück Code:

req.addListener("data", function(chunk) { 
    data += chunk; 
}); 

scheint, dass Anforderungsdaten verketten nicht korrekt ist, so habe ich meine Middleware zu dieser geschaltet:

app.use(function(req, res, next) { 
    var data = []; 
    req.addListener("data", function(chunk) { 
     data.push(new Buffer(chunk)); 
    }); 
    req.addListener("end", function() { 
     buffer = Buffer.concat(data); 
     zlib.inflate(buffer, function(err, result) { 
      if (!err) { 
       req.body = result.toString(); 
       next(); 
      } else { 
       next(err); 
      } 
     }); 
    }); 
}); 

Verketten Puffer funktioniert einwandfrei und ich bin jetzt in der Lage, Anforderung Körper dekomprimiert zu bekommen.

+0

Falls Sie sich fragen, warum *, liegt das daran, dass Ihr erster Versuch darin bestand, rohe Binärdaten in eine Zeichenkette umzuwandeln. Da UTF-8 nicht dazu gedacht ist, willkürliche Bytes zu halten (wie Sie sie in einem komprimierten Datenstrom finden würden), waren Ihre Daten beschädigt. Standardmäßig gibt das Ereignis ['data'] (http://nodejs.org/api/http.html#http_event_data) einen [' Buffer]] (http://nodejs.org/api/buffer.html# buffer_buffer), also die Art und Weise, wie Node mit Rohdaten umgeht. – josh3736

+0

@ josh3736 und Umwandlung in Zeichenfolge verloren einige Daten? Also ist der Chunk schon ein Buffer und ich kann das einfach pushen anstatt einen neuen Buffer zu erstellen? – alex88

+0

[Ja. Aus den Dokumenten für das Ereignis 'data':] (http://nodejs.org/api/http.html#http_event_data) "* Der' Chunk' ist eine Zeichenkette, wenn eine Kodierung mit 'request.setEncoding() gesetzt wurde. ', sonst ist es ein' Buffer'. * " – josh3736

1

Ich weiß, dass dies eine sehr späte Antwort, aber mit Modul body-parser, wird sie:

Returns middleware that only parses json. This parser accepts any Unicode encoding of the body and supports automatic inflation of gzip and deflate encodings.

var bodyParser = require('body-parser'); 
app.use(bodyParser.json());  // to support JSON-encoded bodies 
Verwandte Themen