如何在 Apache 2.x 中使用 mod_deflate 预压缩文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/75482/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 16:43:52  来源:igfitidea点击:

How can I pre-compress files with mod_deflate in Apache 2.x?

apachehttpgzipmod-deflatecontent-encoding

提问by Otto

I am serving all content through apache with Content-Encoding: zipbut that compresses on the fly. A good amount of my content is static files on the disk. I want to gzip the files beforehand rather than compressing them every time they are requested.

我正在通过 apache 提供所有内容,Content-Encoding: zip但会即时压缩。我的大量内容是磁盘上的静态文件。我想事先对文件进行 gzip,而不是每次请求时都压缩它们。

This is something that, I believe, mod_gzipdid in Apache 1.x automatically, but just having the file with .gz next to it. That's no longer the case with mod_deflate.

我相信这是mod_gzip在 Apache 1.x 中自动完成的,但只是在文件旁边有 .gz 。不再是这种情况mod_deflate

采纳答案by Aristotle Pagaltzis

This functionality was misplaced in mod_gzip anyway. In Apache 2.x, you do that with content negotiation. Specifically, you need to enable MultiViewswith the Optionsdirectiveand you need to specify your encoding types with the AddEncodingdirective.

无论如何,此功能在 mod_gzip 中放错了位置。在 Apache 2.x 中,您可以通过内容协商来做到这一点。具体来说,您需要启用MultiViewsOptions指令,你需要与指定的编码类型的AddEncoding指令

回答by Otto

To answer my own question with the really simple line I was missing in my confiuration:

用我在配置中遗漏的非常简单的行来回答我自己的问题:

Options FollowSymLinks MultiViews

I was missing the MultiViews option. It's there in the Ubuntu default web server configuration, so don't be like me and drop it off.

我错过了 MultiViews 选项。它存在于 Ubuntu 默认的 Web 服务器配置中,所以不要像我一样放弃它。

Also I wrote a quick Rake task to compress all the files.

我还编写了一个快速 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

回答by Arno Sch?fer

I am afraid MultiViews will not work as expected: the doc says Multiviews works "if the server receives a request for /some/dir/foo, if /some/dir has MultiViews enabled, and /some/dir/foo does not exist...", in other words: if you have a file foo.js and foo.js.gz in the same directory, just activating MultiViews will not cause the .gz file to be sent even if the AcceptEncoding gzip header is transmitted by the browser (you can verify this behavior by temporarily disabling mod_deflate and monitoring the response with e.g. HTTPFox).

我担心 MultiViews 不会按预期工作:文档说 Multiviews 工作“如果服务器收到对 /some/dir/foo 的请求,如果 /some/dir 启用了 MultiViews,并且 /some/dir/foo 不存在。 ..”,换句话说:如果你有一个文件 foo.js 和 foo.js.gz 在同一个目录下,即使 AcceptEncoding gzip 头是由浏览器(您可以通过暂时禁用 mod_deflate 并使用 HTTPFox 等监视响应来验证此行为)。

I am not sure if there is a way around this with MultiViews (maybe you can rename the original file and then add a special AddEncoding directive), but I believe you can construct a mod_rewrite rule to handle this.

我不确定 MultiViews 是否有办法解决这个问题(也许你可以重命名原始文件,然后添加一个特殊的 AddEncoding 指令),但我相信你可以构建一个 mod_rewrite 规则来处理这个问题。

回答by Kevinoid

It is possible to serve pre-compressed files using mod_negotiationalthough it is a bit finicky. The primary difficulty is that only requests for files which do not exist are negotiated. So if foo.jsand foo.js.gzboth exist, responses for /foo.jswill always be uncompressed (although responses for /foowould work correctly).

mod_negotiation尽管有点挑剔,但可以使用预压缩文件提供服务。主要的困难是只协商对不存在的文件的请求。因此,如果foo.js并且foo.js.gz两者都存在,则响应/foo.js将始终未压缩(尽管响应/foo可以正常工作)。

The easiest solution I've found (from Fran?ois Marier) is to rename uncompressed files with a double file extension, so foo.jsis deployed as foo.js.jsso requests for /foo.jsnegotiate between foo.js.js(no encoding) and foo.js.gz(gzip encoding).

我发现的最简单的解决方案(来自 Fran?ois Marier)是使用双文件扩展名重命名未压缩的文件,因此foo.js部署为(无编码)和(gzip 编码)之间foo.js.js/foo.js协商请求。foo.js.jsfoo.js.gz

I combine that trick with the following configuration:

我将该技巧与以下配置相结合:

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>

I wrote a postwhich discusses the reasoning for this configuration and some alternatives in detail.

写了一篇文章,详细讨论了这种配置的原因和一些替代方案。

回答by brianegge

I have an Apache 2 built from source, and I found I had to modify the following in my httpd.conffile:

我有一个从源代码构建的 Apache 2,我发现我必须在httpd.conf文件中修改以下内容:

Add MultiViews to Options:

将多视图添加到选项:

Options Indexes FollowSymLinks MultiViews
Options Indexes FollowSymLinks MultiViews

Uncomment AddEncoding:

取消注释 AddEncoding:

AddEncoding x-compress .Z
AddEncoding x-gzip .gz .tgz
AddEncoding x-compress .Z
AddEncoding x-gzip .gz .tgz

Comment AddType:

评论添加类型:

#AddType application/x-compress .Z
#AddType application/x-gzip .gz .tgz
#AddType application/x-compress .Z
#AddType application/x-gzip .gz .tgz

回答by Aeon

mod_gzip compressed content on the fly as well. You can pre-compress the files by actually logging into your server, and doing it from shell.

mod_gzip 也可以动态压缩内容。您可以通过实际登录服务器并从 shell 进行预压缩来预压缩文件。

cd /var/www/.../data/
for file in *; do
    gzip -c $file > $file.gz;
done;

回答by Vivien

I have a lot of big .json files. Most readers are in this situation. The preview answers didn't talk about the returned "Content-type".

我有很多大的 .json 文件。大多数读者都处于这种情况。预览答案没有谈论返回的“内容类型”。

I you want the following request return a pre-compressed file with "Content-Type: application/json" transparently, use Multiview with ForceType

我希望以下请求透明地返回一个带有“Content-Type: application/json”的预压缩文件,使用带有 ForceType 的 Multiview

http://www.domain.com/(...)/bigfile.json
-> Content-Encoding:gzip, Content-Type: Content-Encoding:gzip

1) files must be rename: "file.ext.ext"

1)文件必须重命名:“file.ext.ext”

2) Multiview works great with ForceType

2) Multiview 与 ForceType 配合得很好

In the file system:

在文件系统中:

// Note there is no bigfile.json
(...)/bigfile.json.gz
(...)/bigfile.json.json

In your apache config:

在您的 apache 配置中:

<Directory (...)>
    AddEncoding gzip .gz
    Options +Multiviews
    <Files *.json.gz>
        ForceType application/json
    </Files>
</Directory>

Short and simple :)

简短而简单:)

回答by Brian Matthews

You can use mod_cacheto proxy local content in memory or on disk. I don't know if this will work as expected with mod_deflate.

您可以使用mod_cache代理内存或磁盘上的本地内容。我不知道这是否会按预期工作mod_deflate