22

我主持了一个 JavaScript 游戏,它基本上由一个 .html 和一个 .data 文件组成。如果我用 gzip 压缩它们,它们的大小会缩小到 25%。所以我想这样做。

我不是 100% 确定,但我认为使用 mod_gzip 或 mod_deflate 会即时压缩,因为内容没有改变,所以一直在浪费 CPU 时间。

所以我想预编译内容。因此,我在未压缩的文件旁边放了一个 .gz,并将重写规则放在 .htaccess 中:

RewriteEngine on 
# If client accepts compressed files 
RewriteCond %{HTTP:Accept-Encoding} gzip 
# and if compressed file exists 
RewriteCond %{REQUEST_FILENAME}.gz -f 
# send .html.gz instead of .html 
RewriteRule ^(.+)\.(html|css|js|data)$ $1.$2.gz [T=text/$2,E=GZIP:gzip,L] 
Header set Content-Encoding gzip env=GZIP 

重定向工作正常,我可以请求 game.html 并实际上获得了 game.html.gz。但是,浏览器不只是显示它。相反,它会询问我将文件保存在哪里。我该如何解决?或者也许还有另一种方法可以实现我的目标?

4

4 回答 4

19

这就是我如何解决同样的问题。

在 .htaccess 中添加新类型:

AddEncoding gzip .jsgz .cssgz .htmlgz .datagz
AddType application/javascript .jsgz
AddType text/css .cssgz
AddType text/html .htmlgz       
AddType text/plain .datagz

这样做是因为AddType指令不接受 .html.gz 形式的扩展名。

然后修改你的重写规则:

RewriteRule ^(.+)\.(html|css|js|data)$ $1.$2gz [L] 

最后重命名您的文件。从 .html.gz、.js.gz 等中删除点。

完整的 .htaccess 如下所示:

AddEncoding gzip .jsgz .cssgz .htmlgz .datagz
AddType application/x-javascript .jsgz
AddType text/css .cssgz
AddType text/html .htmlgz       
AddType text/plain .datagz

RewriteEngine on 
# If client accepts compressed files 
RewriteCond %{HTTP:Accept-Encoding} gzip 
# and if compressed file exists 
RewriteCond %{REQUEST_FILENAME}gz -f 
# send .html.gz instead of .html 
RewriteRule ^(.+)\.(html|css|js|data)$ $1.$2gz [L] 
于 2013-06-02T14:15:32.563 回答
10

你应该问自己的第一个问题是,这样做有什么意义吗?您是否因此注意到过高的 CPU 负载和/或性能差异?我的猜测是你可能没有遇到这个问题:)

无论如何,有多种方法可以解决您的问题。

  1. 可能是您的最佳选择,使用 CDN。它们专为快速交付静态文件而设计,可为不同地理区域的人们以及靠近服务器的人们提供快速传输。此外,根据我的经验,CDN 通常比您自己的带宽便宜得多。

  2. 使用 Nginx。用于更快地托管静态文件,并支持像您现在所做的那样预生成静态内容。它会自动检测是否有.gz文件并在需要时提供该文件。

  3. 使用 Apache 缓存机制之一,例如mod_mem_cachemod_disk_cache确保每个经常使用的文件都在缓存中。教程:http ://webdirect.no/linux/apache-caching-with-gzip-enabled/

  4. 在它前面使用像 Varnish 这样的缓存代理,这些类型的服务器具有更智能的缓存机制,并且实际上会缓存最重要的文件。

但是,对于您当前的版本,这样的东西(未经测试)应该可以解决问题:

RewriteEngine On    
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule ^(.*)\.(html|css|js|data) $1\.$2\.gz [QSA]

# Prevent double gzip and give the correct mime-type
RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1,E=FORCE_GZIP]
RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1,E=FORCE_GZIP]
RewriteRule \.html\.gz$ - [T=text/html,E=no-gzip:1,E=FORCE_GZIP]
RewriteRule \.data\.gz$ - [T=text/plain,E=no-gzip:1,E=FORCE_GZIP]

Header set Content-Encoding gzip env=FORCE_GZIP
于 2013-06-02T14:03:31.517 回答
7

接受的答案似乎很痛苦。 Wolph 的答案似乎更好,但仍然需要为每个文件扩展名单独配置,并且缺乏对更高级协商(q-valuesstatus 406TCN等)的支持。与其自己使用实现内容协商mod_rewrite,不如考虑使用此问题mod_negotiation中讨论的方法。从那里复制我的答案:

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文件,而不仅仅是显式配置的文件,并且可以轻松扩展为brotli或其他编码。

它确实有一个主要缺点,因为只有对不存在的文件的请求才会被协商,一个名为的文件foo.js会请求/foo.js(但不是/foo)返回未压缩的版本。使用François Marier使用双扩展名重命名未压缩文件的解决方案可以避免这种情况,因此foo.js部署为foo.js.js.

于 2016-01-21T19:12:43.477 回答
3

这里概述的解决方案怎么样:http: //feeding.cloud.geek.nz/posts/serving-pre-compressed-files-using/。使用 Apache 的内置 MultiViews...

于 2014-02-14T23:29:16.080 回答