2012-09-25 20 views
7

Sono abbastanza nuovo su node.js e sto tentando di inviare un file zip contenente i risultati JSON. Ho cercato di capire come farlo, ma non ho avuto i risultati attesi.Risposta JSON Zip in node.js

Sto utilizzando NodeJS, ExpressJS, LocomotiveJS, Mongoose e MongoDB.

Dato che stiamo costruendo un'applicazione orientata al mobile, sto cercando di salvare il maggior numero di banda possibile.

Il carico iniziale giornaliero per l'app mobile potrebbe essere un grande documento JSON, quindi voglio comprimerlo prima di inviarlo al dispositivo. Se possibile mi piacerebbe farlo tutto in memoria per evitare l'I/O del disco.

Ho provato con 3 biblioteche finora:

  • ADM-zip
  • nodo-zip
  • zipstream

Il miglior risultato ottenuto è usando nodo-zip. Qui è il mio codice:

return Queue.find({'owners': this.param('id')}).select('name extra_info cycle qtype purge purge_time tasks').exec(function (err, docs) { 
    if (!err) { 
     zip.file('queue.json', docs); 
     var data = zip.generate({base64:false,compression:'DEFLATE'}); 

     res.set('Content-Type', 'application/zip'); 
     return res.send(data); 
    } 
    else { 
     console.log(err); 
     return res.send(err); 
    } 
    }); 

Il risultato è un file zip scaricato, ma il contenuto è illeggibile.

Sono quasi sicuro che sto confondendo le cose, ma a questo punto non sono sicuro di come procedere.

Qualche consiglio?

Grazie a advace

risposta

17

È possibile comprimere l'uscita in veloce 3 con questo:

app.configure(function(){ 
    //.... 
    app.use(express.compress()); 
}); 


app.get('/foo', function(req, res, next){ 
    res.send(json_data); 
}); 

Se l'agente utente supporta gzip sarà gzip per voi automaticamente.

+0

Grazie chovy, ha funzionato! – AkerbeltZ

+1

E 'stato facile. – prototype

+0

Dove devo mantenere il middleware express.compress()? prima di percorsi e contenuti statici o dopo di loro? – arunkjn

0

Credo che si intende come faccio a inviare contenuto Gzip con il nodo?

Il nodo versione 0.6 e successive dispone di un modulo integrato zlip, quindi non è necessario richiedere moduli esterni.

È possibile inviare contenuti Gzip come questo.

response.writeHead(200, { 'content-encoding': 'gzip' }); 
    json.pipe(zlib.createGzip()).pipe(response); 

Ovviamente è necessario prima del tempo di controllo il cliente accetta la codifica Gzip e ricordare anche gzip è un'operazione costosa così si dovrebbe memorizzare nella cache i risultati.

Qui è pieno esempio prendendo dal docs

// server example 
// Running a gzip operation on every request is quite expensive. 
// It would be much more efficient to cache the compressed buffer. 
var zlib = require('zlib'); 
var http = require('http'); 
var fs = require('fs'); 
http.createServer(function(request, response) { 
    var raw = fs.createReadStream('index.html'); 
    var acceptEncoding = request.headers['accept-encoding']; 
    if (!acceptEncoding) { 
    acceptEncoding = ''; 
    } 

    // Note: this is not a conformant accept-encoding parser. 
    // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3 
    if (acceptEncoding.match(/\bdeflate\b/)) { 
    response.writeHead(200, { 'content-encoding': 'deflate' }); 
    raw.pipe(zlib.createDeflate()).pipe(response); 
    } else if (acceptEncoding.match(/\bgzip\b/)) { 
    response.writeHead(200, { 'content-encoding': 'gzip' }); 
    raw.pipe(zlib.createGzip()).pipe(response); 
    } else { 
    response.writeHead(200, {}); 
    raw.pipe(response); 
    } 
}).listen(1337); 
+0

Ciao Saeed, grazie per la risposta. Il problema è che la soluzione mobile che utilizziamo (Titanium SDK) non supporta i file gzip. – AkerbeltZ

1

Per Express 4+, la compressione non viene fornita in bundle con Express e deve essere installata separatamente.

$ npm install compression 

quindi di utilizzare la libreria:

var compression = require('compression'); 
app.use(compression()); 

Ci sono un sacco di opzioni è possibile sintonizzare, see here for the list.