2012-09-25 24 views
7

Jestem całkiem nowy dla node.js i próbuję odesłać plik zip zawierający wyniki JSON. Próbowałem to rozgryźć, ale nie przyniosłem oczekiwanych rezultatów.JSON Zip Response w node.js

Używam NodeJS, ExpressJS, LocomotiveJS, Mongoose i MongoDB.

Odkąd tworzymy aplikację mobilną, staram się oszczędzać jak najwięcej pasm.

Dzienne obciążenie początkowe aplikacji mobilnej może być dużym dokumentem JSON, dlatego chcę go spakować przed wysłaniem do urządzenia. Jeśli to możliwe, chciałbym zrobić to wszystko w pamięci, aby uniknąć operacji we/wy dysku.

Próbowałem z 3 bibliotek dotąd:

  • ADM-zip
  • node-Zip
  • zipstream

Najlepszy rezultat osiąga się stosując ja node-zip. Oto mój kod:

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); 
    } 
    }); 

Wynikiem jest pobrany plik zip, ale jego zawartość jest nieczytelna.

Jestem prawie pewna, że ​​miksuję różne rzeczy, ale do tego momentu nie jestem pewien, jak postępować.

Dowolna porada?

Dzięki z advace

Odpowiedz

17

można skompresować wyjście w wyraźnej 3 z tym:

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


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

Jeśli aplikacja kliencka obsługuje gzip będzie gzip go automatycznie.

+0

Dzięki chovy, zadziałało! – AkerbeltZ

+1

Yikes to było łatwe. – prototype

+0

Gdzie powinienem przechowywać oprogramowanie pośredniczące express.compress()? przed trasami i statyczną zawartością lub po nich? – arunkjn

0

Chyba masz na myśli, jak mogę wysłać treść Gzip z węzła?

Węzeł w wersji 0.6 i nowszej ma wbudowany moduł zlip, więc nie ma potrzeby wymagać modułów zewnętrznych.

Możesz wysyłać treść Gzip w ten sposób.

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

Oczywiście trzeba będzie pogoda czeka najpierw klient akceptuje kodowanie Gzip i również pamiętać gzip jest kosztowna operacja więc należy buforować wyniki.

Oto pełna przykład biorąc od 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

Cześć, Saeed, dziękuję za odpowiedź. Problem polega na tym, że rozwiązanie mobilne, z którego korzystamy (Titanium SDK), nie obsługuje plików gzip. – AkerbeltZ

1

W przypadku Express 4+ kompres nie jest dostarczany w pakiecie z Expressem i wymaga osobnej instalacji.

$ npm install compression 

Następnie użyć biblioteki:

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

Istnieje kilka opcji można dostroić, see here for the list.