ruby - 在带有 Ruby 的 Sinatra 中使用 gzip 压缩

标签 ruby sinatra gzip zlib

注意:我有另一个类似的问题,关于如何使用 Ruby 的 zlib 对数据进行 GZIP 压缩,技术上 得到了回答,我觉得我不能开始改进这个问题,因为它已经回答了,所以虽然这个问题是相关的,但并不相同......

以下代码(我相信)是对静态 CSS 文件进行 GZIP 压缩并将结果存储在 result 变量中。但是从某种意义上说,我该怎么做:我怎样才能将这些数据发送回浏览器,以便它被识别为 GZIP 压缩而不是原始文件大小(例如,当检查我的 YSlow 分数时,我想看到它正确标记我确保我 GZIP 静态资源)。

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

...需要注意的是,在我之前的问题中,受访者澄清说 Zlib::Deflate.deflate 不会生成 gzip 编码的数据。它只会生成 zlib 编码的数据,因此我需要使用 Zlib::Deflate.new 并将 windowBits 参数设置为 31 来启动 gzip 流。

但是当我运行这段代码时,我实际上并不知道如何处理 result 变量及其内容。互联网上(我能找到)没有关于如何将 GZIP 编码的静态资源(如 JavaScript、CSS、HTML 等)发送到浏览器的信息,这使得页面加载速度更快。似乎我阅读的每篇 Ruby 文章都是基于使用 Ruby on Rails 的人!!?

非常感谢任何帮助。

最佳答案

压缩文件后,您只需返回结果并确保为响应设置 header Content-Encoding: gzip。谷歌有一个不错的小introduction gzip 压缩以及您必须注意的事项。以下是您可以在 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

不过,最后要提醒一句。您可能应该仅对动态创建的内容或您只想在几个地方使用 gzip 压缩的内容选择此方法。

但是,如果您的目标是在启用 gzip 压缩的情况下为大部分甚至所有静态资源提供服务,那么依赖您的网络服务器已经支持的内容而不是污染您的代码将是一个更好的解决方案这个细节。您很有可能可以通过一些配置设置启用 gzip 压缩。 Here's nginx 如何完成的示例。

另一种选择是使用 Rack::Deflater中间件。

关于ruby - 在带有 Ruby 的 Sinatra 中使用 gzip 压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11072710/

相关文章:

ruby - 解释简洁的 ruby​​ 'nil' 错误

ruby-on-rails - Rails 在模型中定义无记录检查

html - 将默认值设置为 html 中的空白表单。(Ruby、Sinatra、CSS)

java - 如何将字符串转换为 GZIP Base64 字符串?

php - 存储 GZIP :ed text in mysql?

ruby - 如何在 Ruby 中获取 `required` 的文件列表?

c++ - 为 Homebrew 软件构建 C++ 公式

ruby - 机架 OAuth-2 服务器中的 Web 服务器流

ruby - Sinatra App 作为一个类——为什么要这样做?

c - 高效查找和替换 gzip 内容上的数据