如何强制Apache使用手动预压缩的CSS和JS文件的gz文件?

时间:2012-01-31 08:50:11

标签: apache caching gzip

我有一个简单的问题。我有webdirectory /css,里面是文件style.css。我手动gzipped这个文件并将其保存为style.css.gz。我想节省CPU周期,以便在每次请求时都没有压缩CSS文件。如何配置Apache以查找此.gz文件并提供它而不是一遍又一遍地压缩.css文件?

注意:我不希望Apache自己创建.gz文件。在我的场景中,我必须手动创建.css.gz文件 - 在特定请求上使用PHP。

6 个答案:

答案 0 :(得分:50)

一些RewriteRule应该很好地处理它。

在Drupal配置文件中,我发现:

# AddEncoding allows you to have certain browsers uncompress information on the fly.
AddEncoding gzip .gz

#Serve gzip compressed CSS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.css $1\.css\.gz [QSA]

# Serve gzip compressed JS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.js $1\.js\.gz [QSA]

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

这将成为工作。如果您无法访问apache配置或者想要减慢Web服务器的速度,可以将其放在<Directory foo/>部分或.htaccess文件中。

答案 1 :(得分:9)

继续使用regilero回答你还应该添加几行,以确保服务器使用相应的Content-Encoding标头回答:

#Serve gzip compressed CSS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.css $1\.css\.gz [QSA]

# Serve gzip compressed JS files if they exist and the client accepts gzip.
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.js $1\.js\.gz [QSA]

# Serve correct content types, and prevent mod_deflate double gzip.
RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1,E=is_gzip:1]
RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1,E=is_gzip:1]
Header set Content-Encoding "gzip" env=is_gzip

答案 2 :(得分:6)

我意识到这不是你问的问题,但无论如何我都把它扔出去了。您是否考虑过将mod_cachemod_gzip一起使用?使用正确的配置,apache将为您压缩文件,然后将压缩的缓存文件传递给客户端和下游代理。这比您在时间和精力方面的建议更有效,并且在带宽和计算负荷方面同样有效。

PHP首先压缩文件并不重要,因为正确设置mod_gzip会检测到它。重点是你可以缓存压缩文件,Apache不会重新压缩它们。

答案 3 :(得分:6)

您可以使用mod_rewrite(而忽略更高级的功能,例如content negotiationq-valuesstatus 406等)来实施TCN。想要使用this question中讨论的mod_negotiation。从那里复制my answer

Options +MultiViews
RemoveType .gz
AddEncoding gzip .gz
<FilesMatch ".+\.tar\.gz$">
    RemoveEncoding .gz
    # Note:  Can use application/x-gzip for backwards-compatibility
    AddType application/gzip .gz
</FilesMatch>

这样可以为所有.gz个文件而不仅仅是.css.gz.js.gz工作,并且可以轻松扩展以进行其他编码。

它确实有一个主要缺点,因为 only requests for files which do not exist are negotiated 名为foo.js的文件会请求/foo.js(但不是/foo)返回未压缩的版本。使用François Marier's solution重命名具有双重扩展名的未压缩文件可以避免这种情况,因此foo.js部署为foo.js.js。如果此限制对您的部署过程来说不会太痛苦,那么使用mod_negotiation可能值得考虑。

答案 4 :(得分:1)

不是this blog post正是你要找的一步一步吗?

  

我们检查文件的这个gzip压缩版本是否存在(第四行),如果存在,我们将.gz附加到请求的文件名

答案 5 :(得分:0)

我对所提出的解决方案有些挣扎。对于将VirtualHosts与其他DocumentRoots一起使用的其他人,只需将RewriteCond更改为:

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME}\.gz -s