2012-09-25 39 views
7

Tôi khá mới đối với node.js và tôi đang cố gắng gửi lại tệp nén chứa kết quả JSON. Tôi đã cố gắng tìm ra cách để làm điều đó, nhưng chưa có kết quả mong đợi.Phản hồi Zip JSON trong node.js

Tôi đang sử dụng NodeJS, ExpressJS, LocomotiveJS, Mongoose và MongoDB.

Vì chúng tôi đang xây dựng một ứng dụng di động theo định hướng, tôi đang cố gắng tiết kiệm càng nhiều băng thông càng tốt.

Tải ban đầu hàng ngày cho ứng dụng dành cho thiết bị di động có thể là tài liệu JSON lớn, vì vậy tôi muốn nén nó trước khi gửi cho thiết bị. Nếu có thể tôi muốn làm mọi thứ trong bộ nhớ để tránh đĩa I/O.

Tôi đã thử với 3 thư viện cho đến nay:

  • adm-zip
  • nút-zip
  • zipstream

Kết quả tốt nhất mà tôi đạt được là sử dụng nút-zip. Đây là mã của tôi:

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

Kết quả là tệp zip đã tải xuống nhưng nội dung không thể đọc được.

Tôi khá chắc chắn rằng tôi đang trộn lẫn mọi thứ, nhưng đến thời điểm này tôi không chắc chắn làm thế nào để tiến hành.

Bất kỳ lời khuyên nào?

Cảm ơn bạn đã advace

Trả lời

17

Bạn có thể nén đầu ra trong nhanh 3 với điều này:

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


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

Nếu user agent hỗ trợ gzip nó sẽ gzip nó cho bạn tự động.

+0

Cảm ơn chovy, nó đã hoạt động! – AkerbeltZ

+1

Yikes dễ dàng. – prototype

+0

Tôi nên giữ phần mềm trung gian express.compress() ở đâu? trước các tuyến đường và nội dung tĩnh hoặc sau chúng? – arunkjn

0

Tôi nghĩ bạn có nghĩa là làm cách nào để gửi nội dung Gzip bằng nút?

Nút phiên bản 0.6 trở lên có mô-đun zlip được tích hợp sẵn, vì vậy không cần phải yêu cầu mô-đun bên ngoài.

Bạn có thể gửi nội dung Gzip như thế này.

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

Rõ ràng trước tiên bạn cần kiểm tra thời tiết khách hàng chấp nhận mã hóa Gzip và nhớ gzip là thao tác tốn kém, do đó bạn nên lưu kết quả.

Dưới đây là ví dụ hoàn lấy từ các tài liệu

// 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

Hi Saeed, cảm ơn câu trả lời của bạn. Vấn đề là giải pháp di động chúng tôi sử dụng (Titanium SDK) không hỗ trợ các tệp gzip. – AkerbeltZ

1

Đối với Express 4+, nén không đi kèm với Express và cần được cài đặt riêng.

$ npm install compression 

Sau đó, để sử dụng thư viện:

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

Có một loạt các tùy chọn bạn có thể điều chỉnh, see here for the list.

Các vấn đề liên quan