我主持一个基本上由.html和.data文件组成的JavaScript游戏。如果我用gzip压缩它们,它们的大小会缩小到25%。所以我想这样做。
我不是百分百肯定,但我认为使用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.但是,浏览器不会只显示它。相反,它会询问我保存文件的位置。我该如何解决这个问题?或者也许有另一种方法来实现我的目标?
答案 0 :(得分:18)
这就是我一旦解决同样问题的方法。
在.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]
答案 1 :(得分:9)
你应该问自己的第一个问题是,这样做有什么意义吗?你是否注意到CPU负载和/或性能差异太大?我的猜测是你可能没有遇到这个问题:)
无论如何,有多种方法可以解决您的问题。
可能是您的最佳选择,请使用CDN。它们专为快速传送静态文件而设计,可以让不同地理区域的人以及服务器附近的人快速访问。另外,根据我的经验,CDN通常比你自己的带宽便宜得多。
使用Nginx。用于更快地托管静态文件更多,并支持预生成静态内容,就像您现在正在做的那样。它会自动检测是否有.gz
文件,并在需要时提供该文件。
使用其中一个Apache缓存机制,如mod_mem_cache
或mod_disk_cache
,以确保每个常用文件都在缓存中。教程:http://webdirect.no/linux/apache-caching-with-gzip-enabled/
在它前面使用像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
答案 2 :(得分:6)
接受的答案似乎很痛苦。 Wolph's answer似乎更好,但仍然需要为每个文件扩展名单独配置,并且不支持更高级的协商(q-values,status 406,TCN等)。您可以考虑使用content negotiation中讨论的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>
自己实施this question。从那里复制my answer:
.gz
这为所有foo.js
个文件提供了额外的好处,而不仅仅是明确配置的文件,并且可以轻松扩展brotli或其他编码。
它确实有一个主要缺点,因为 only requests for files which do not exist are negotiated 名为/foo.js
的文件会请求/foo
(但不是foo.js
)返回未压缩的版本。使用François Marier's solution重命名具有双重扩展名的未压缩文件可以避免这种情况,因此foo.js.js
部署为class Customer < ActiveRecord::Base
has_many :jobs, dependent: :destroy
end
class Job < ActiveRecord::Base
belongs_to :customer
has_many :receipts, dependent: :destroy
end
class Receipt < ActiveRecord::Base
belongs_to :job
end
。
答案 3 :(得分:3)
此处列出的解决方案如何:http://feeding.cloud.geek.nz/posts/serving-pre-compressed-files-using/。使用Apache的内置MultiViews ......