注意

有人建议这是如何使用.htaccess提供预压缩的gzip/brotli文件的副本。该问题仅用于提供pre-compressed文件。这个问题是不同的。请看下面。

我的目标

我想提供pre-compressed brotli文件(如果存在)。如果不存在pre-compressed brotli文件,请回退到on-the-fly gzip-compression。

当前代码

我正在一个已经从其.htaccess文件启用on-the-fly gzip的网站上,如下所示:

<ifmodule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml...
</ifmodule>

修改后的代码

我已经设置了一个构建脚本,该脚本使用brotli压缩了许多静态资产。为了服务他们,我将以下mod_deflate块替换为:

<IfModule mod_headers.c>
    # Serve brotli compressed CSS and JS files if they exist
    # and the client accepts brotli.
    RewriteCond "%{HTTP:Accept-encoding}" "br"
    RewriteCond "%{REQUEST_FILENAME}\.br" "-s"
    RewriteRule "^(.*)\.(js|css)"              "$1\.$2\.br" [QSA]

    # Serve correct content types, and prevent double compression.
    RewriteRule "\.css\.br$" "-" [T=text/css,E=no-brotli:1]
    RewriteRule "\.js\.br$"  "-" [T=text/javascript,E=no-brotli:1]

    <FilesMatch "(\.js\.br|\.css\.br)$">
        # Serve correct encoding type.
        Header append Content-Encoding br

        # Force proxies to cache brotli &
        # non-brotli css/js files separately.
        Header append Vary Accept-Encoding
    </FilesMatch>
</IfModule>

问题

当brotli-encoded文件按预期存在时,它将为brotli-encoded文件提供服务。但是,我现在面临的问题是,由于在构建时剩余资产不是brotli-encoded,因此现在无需压缩即可使用它们。

我一直无法弄清楚如何用不带Xzip的gzip后备服务来为brotli服务,而无需将pre-compress用于gzip输出。

任何帮助表示赞赏,谢谢!

分析解答

您的问题是您将动态gzip配置替换为静态配置。

您既需要配置位,也需要更改Brotli代码以将环境设置为no-gzip,这样它就不会退路。以下应该工作;

<ifmodule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml...
</ifmodule>

<IfModule mod_headers.c>
    # Serve brotli compressed CSS and JS files if they exist
    # and the client accepts brotli.
    RewriteCond "%{HTTP:Accept-encoding}" "br"
    RewriteCond "%{REQUEST_FILENAME}\.br" "-s"
    RewriteRule "^(.*)\.(js|css)"              "$1\.$2\.br" [QSA]

    # Serve correct content types, and prevent double compression.
    RewriteRule "\.css\.br$" "-" [T=text/css,E=no-gzip:1]
    RewriteRule "\.js\.br$"  "-" [T=text/javascript,E=no-gzip:1]

    <FilesMatch "(\.js\.br|\.css\.br)$">
        # Serve correct encoding type.
        Header append Content-Encoding br

        # Force proxies to cache brotli &
        # non-brotli css/js files separately.
        Header append Vary Accept-Encoding
    </FilesMatch>
</IfModule>