2012-06-17 35 views
8

Lưu ý: Tôi có một câu hỏi tương tự khác về cách GZIP sử dụng dữ liệu của Ruby về mặt kỹ thuật và tôi không cảm thấy mình có thể bắt đầu phát triển câu hỏi. câu hỏi này liên quan đến nó không giống nhau ...Sử dụng nén gzip ở Sinatra với Ruby

Mã sau đây (tôi tin) là GZIP'ing tệp CSS tĩnh và lưu trữ kết quả trong biến số result. Nhưng tôi phải làm gì với ý nghĩa này: làm cách nào để gửi dữ liệu này trở lại trình duyệt để nó được nhận dạng là GZIP'ed chứ không phải kích thước tệp gốc (ví dụ: khi kiểm tra điểm số YSlow của tôi, tôi muốn thấy nó chính xác tôi để đảm bảo rằng tôi GZIP tài nguyên tĩnh).

z = Zlib::Deflate.new(6, 31) 
z.deflate(File.read('public/Assets/Styles/build.css')) 
z.flush 
@result = z.finish # could also of done: result = z.deflate(file, Zlib::FINISH) 
z.close 

... một điều cần lưu ý là trong câu hỏi trước, người trả lời đã làm rõ rằng Zlib::Deflate.deflate sẽ không tạo dữ liệu được mã hóa gzip. Nó sẽ chỉ tạo ra dữ liệu được mã hóa zlib và vì vậy tôi sẽ cần sử dụng Zlib::Deflate.new với đối số windowBits bằng 31 để bắt đầu luồng gzip.

Nhưng khi tôi chạy mã này tôi thực sự không biết phải làm gì với biến số result và nội dung của nó. Không có thông tin trên internet (mà tôi có thể tìm thấy) về cách gửi các tài nguyên tĩnh được mã hóa GZIP (như JavaScript, CSS, HTML v.v.) cho trình duyệt, điều này làm cho trang tải nhanh hơn. Có vẻ như mọi bài viết Ruby tôi đọc đều dựa trên một người nào đó sử dụng Ruby on Rails !!?

Bất kỳ trợ giúp nào thực sự đánh giá cao.

Trả lời

13

Sau khi nén tệp, bạn chỉ cần trả về kết quả và đảm bảo đặt tiêu đề Content-Encoding: gzip cho phản hồi. Google có một số ít đẹp introduction để nén gzip và những gì bạn phải xem. Dưới đây là những gì bạn có thể làm trong Sinatra:

get '/whatever' do 
    headers['Content-Encoding'] = 'gzip' 
    StringIO.new.tap do |io| 
    gz = Zlib::GzipWriter.new(io) 
    begin 
     gz.write(File.read('public/Assets/Styles/build.css')) 
    ensure 
     gz.close 
    end 
    end.string 
end 

Một lời cảnh cáo cuối cùng. Bạn có lẽ nên chọn cách tiếp cận này chỉ cho nội dung mà bạn tạo ra trên bay hoặc nếu bạn chỉ muốn sử dụng nén gzip ở một vài nơi.

Nếu, tuy nhiên, mục tiêu của bạn là phân phối hầu hết hoặc thậm chí tất cả tài nguyên tĩnh của bạn với tính năng nén gzip, sau đó sẽ là giải pháp tốt hơn để dựa vào những gì đã được máy chủ web hỗ trợ thay vì gây ô nhiễm mã của bạn với chi tiết này. Có một cơ hội tốt để bạn có thể bật tính năng nén gzip với một số cài đặt cấu hình. Here's một ví dụ về cách nó được thực hiện cho nginx.

Một giải pháp thay thế khác là sử dụng phần mềm trung gian Rack::Deflater.

+1

Cảm ơn bạn đã trả lời chi tiết và mã ví dụ. Tôi đã đưa ra ý kiến ​​của bạn và sử dụng 'Rack :: Deflater' để thay thế. Nghĩa là một dòng mã ở đầu tệp ứng dụng của tôi và nó hoạt động: 'sử dụng Rack :: Deflater' – Integralist

+0

+1 cho tùy chọn nginx –

+0

Bị bỏ qua vì điều này sẽ phục vụ nội dung gzipped bất kể những gì khách hàng đã chỉ định họ có thể chấp nhận trong 'Accept-Encoding' header. Đây là, tất nhiên, thực hành xấu và nên tránh. – aidan

3

Chỉ cần để làm nổi bật 'Kệ :: Deflater' cách như một 'câu trả lời' ->

Như đã đề cập trong các bình luận ở trên, chỉ cần đặt nén trong config.ru

use Rack::Deflater 

thats khá nhiều nó!

+0

Đây là câu trả lời tốt hơn vì 'Rack :: Deflate' sẽ thương lượng và sử dụng thuật toán nén tốt nhất mà máy khách hỗ trợ – aidan