如何在 Apache 2.x 中使用 mod_deflate 预压缩文件?
-
09-06-2019 - |
题
我通过 apache 提供所有内容 Content-Encoding: zip
但这是动态压缩的。我的大部分内容都是磁盘上的静态文件。我想预先对文件进行 gzip 压缩,而不是每次请求时都对其进行压缩。
我相信,这是一件事, mod_gzip
在 Apache 1.x 中自动执行,但只是在其旁边带有 .gz 文件。现在情况已不再是这样了 mod_deflate
.
解决方案
无论如何,这个功能在 mod_gzip 中被放错了位置。在阿帕奇 2.x 中, 你可以通过内容协商来做到这一点. 。具体来说,您需要启用 MultiViews
与 Options
指示 并且您需要使用指定编码类型 AddEncoding
指示.
其他提示
用我在配置中缺少的非常简单的行来回答我自己的问题:
Options FollowSymLinks MultiViews
我缺少多视图选项。它存在于 Ubuntu 默认 Web 服务器配置中,所以不要像我一样将其删除。
我还编写了一个快速 Rake 任务来压缩所有文件。
namespace :static do
desc "Gzip compress the static content so Apache doesn't need to do it on-the-fly."
task :compress do
puts "Gzipping js, html and css files."
Dir.glob("#{RAILS_ROOT}/public/**/*.{js,html,css}") do |file|
system "gzip -c -9 #{file} > #{file}.gz"
end
end
end
恐怕 MultiViews 不会按预期工作:文档说 Multiviews 工作“如果服务器收到对 /some/dir/foo 的请求,如果 /some/dir 启用了 MultiViews,并且 /some/dir/foo 不存在......”,换句话说:如果您在同一目录中有文件 foo.js 和 foo.js.gz,即使浏览器传输了 AcceptEncoding gzip 标头,仅激活 MultiViews 也不会导致 .gz 文件被发送(您可以通过以下方式验证此行为)暂时禁用 mod_deflate 并监控响应,例如HTTPFox)。
我不确定是否有办法通过 MultiViews 解决这个问题(也许您可以重命名原始文件,然后添加一个特殊的 AddEncoding 指令),但我相信您可以构造一个 mod_rewrite 规则来处理这个问题。
我有一个从源代码构建的 Apache 2,我发现我必须在我的 httpd.conf 文件:
将多视图添加到选项:
Options Indexes FollowSymLinks MultiViews
取消注释 AddEncoding:
AddEncoding x-compress .Z AddEncoding x-gzip .gz .tgz
评论添加类型:
#AddType application/x-compress .Z #AddType application/x-gzip .gz .tgz
可以使用以下方式提供预压缩文件 mod_negotiation
虽然有点挑剔。主要的困难是 仅协商对不存在的文件的请求. 。因此,如果 foo.js
和 foo.js.gz
两者都存在,回应 /foo.js
将始终是未压缩的(尽管响应 /foo
会正常工作)。
我发现的最简单的解决方案(弗朗索瓦·马里尔)是用双文件扩展名重命名未压缩的文件,所以 foo.js
部署为 foo.js.js
所以要求 /foo.js
之间进行谈判 foo.js.js
(无编码)和 foo.js.gz
(gzip 编码)。
我将该技巧与以下配置结合起来:
Options +MultiViews
RemoveType .gz
AddEncoding gzip .gz
# Send .tar.gz without Content-Encoding: gzip
<FilesMatch ".+\.tar\.gz$">
RemoveEncoding .gz
# Note: Can use application/x-gzip for backwards-compatibility
AddType application/gzip .gz
</FilesMatch>
我 写了一篇文章 其中详细讨论了此配置的原因和一些替代方案。
mod_gzip 也可以动态压缩内容。您可以通过实际登录服务器并从 shell 执行此操作来预压缩文件。
cd /var/www/.../data/
for file in *; do
gzip -c $file > $file.gz;
done;
您可以使用 mod_cache
代理内存或磁盘上的本地内容。我不知道这是否会按预期工作 mod_deflate
.
我有很多大的 .json 文件。大多数读者都处于这种情况。预览答案没有谈论返回的“Content-type”。
我希望以下请求返回一个带有“Content-Type:”的预压缩文件application/json" 透明地使用 Multiview 和 ForceType
http://www.domain.com/(...)/bigfile.json
-> Content-Encoding:gzip, Content-Type: Content-Encoding:gzip
1)文件必须重命名:“文件.ext.ext”
2) 多视图与 ForceType 配合得很好
在文件系统中:
// Note there is no bigfile.json
(...)/bigfile.json.gz
(...)/bigfile.json.json
在你的 apache 配置中:
<Directory (...)>
AddEncoding gzip .gz
Options +Multiviews
<Files *.json.gz>
ForceType application/json
</Files>
</Directory>
简短而简单:)