压缩 HTML、CSS 和 HTML 的最佳方法 禁用 mod_deflate 和 mod_gzip 的 JS
我在运行 Apache 2 的共享主机上有几个站点。我想压缩传送到浏览器的 HTML、CSS 和 Javascript。 主机已禁用 mod_deflate 和 mod_gzip,因此这些选项无效。 不过,我确实有 PHP 5,所以我可以使用它的 gzip 组件。
我目前将以下内容放入我的 .htaccess 文件中:
php_value 输出处理程序 ob_gzhandler
但是,这仅压缩 HTML,而忽略 CSS 和 JS。
有没有一种可靠的方法可以透明地压缩 CSS 和 JS 的输出,而不必更改每个页面? 我在谷歌上搜索过,并提出了许多解决方案,但我还没有找到一个可以工作的解决方案。 如果有人能提出一个他们知道可行的解决方案,我们将非常感激。
请注意,方法 2 "noreferrer">关于压缩 CSS 的权威文章 看起来是一个很好的解决方案,但我无法让它发挥作用。 有其他人使用此方法成功吗?
I have a few sites on a shared host that is running Apache 2. I would like to compress the HTML, CSS and Javascript that is delivered to the browser. The host has disabled mod_deflate and mod_gzip, so these options are out. I do have PHP 5 at my disposal, though, so I could use the gzip component of that.
I am currently placing the following in my .htaccess file:
php_value output_handler ob_gzhandler
However, this only compresses the HTML and leaves out the CSS and JS.
Is there a reliable way of transparently compressing the output of the CSS and JS without having to change every page? I have searched Google and a number of solutions are presented, but I've yet to get one to work. If anyone could suggest a solution that they know to work, that would be very gratefully received.
Note, Method 2 in The Definitive Post on Gzipping your CSS looks like a good solution, but I couldn't get it working. Has anyone else succeeded using this method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我所做的:
js
目录中,将样式表放置在css
目录中。在 Apache 配置中,我添加如下指令:
js
目录中的gzip-js.php 如下所示:
<前><代码>
...而
css
目录中的 gzip-cs.php 如下所示像这样:<前><代码>
这可能不是最优雅的解决方案,但它肯定是一个简单的解决方案,需要很少的变化并且运作良好。
What I do:
js
and stylesheets in acss
dir, respectively.In the Apache configuration, I add directives like so:
gzip-js.php in the
js
directory looks like this:…and gzip-cs.php in the
css
directory looks like this:This may not be the most elegant solution, but it most certainly is a simple one that requires few changes and works well.
抱歉耽搁了——这对我来说是忙碌的一周。
假设:
.htaccess
与compress.php
位于同一个文件中static
子目录中我从设置.htaccess 中的以下指令:
您的提供商需要允许您覆盖
.htaccess
文件中的mod_rewrite
选项。那么 compress.php 文件本身可以如下所示:
您当然应该向 switch 语句添加更多 mime 类型。 我不想让解决方案依赖于 pecl
fileinfo
扩展或任何其他神奇的 mime 类型检测库 - 这是最简单的方法。至于保护脚本 - 我将其转换为文件系统中的真实路径,因此不会出现被黑的“../../../etc/passwd”或其他 shellscript 文件路径。
这就是
片段。 尽管我非常确定除 $basedir 以外的其他层次结构中的大多数路径在到达脚本之前都会由 Apache 处理。
我还检查生成的路径是否位于脚本的目录树内。
按照 pilif 的建议添加缓存控制的标头,您应该可以找到解决问题的方法。
Sorry about the delay - it's a busy week for me.
Assumptions:
.htaccess
is in the same file ascompress.php
static
subdirectoryI started my solution from setting the following directives in .htaccess:
It's required that your provider allows you to override
mod_rewrite
options in.htaccess
files.Then the compress.php file itself can look like this:
You should of course add more mime types to the switch statement. I didn't want to make the solution dependant on the pecl
fileinfo
extension or any other magical mime type detecting libraries - this is the simplest approach.As for securing the script - I do a translation to a real path in the file system so no hacked '../../../etc/passwd' or other shellscript file paths don't go through.
That's the
snippet. Although I'm pretty sure most of the paths that are in other hierarchy than $basedir will get handled by the Apache before they even reach the script.
Also I check if the resulting path is inside the script's directory tree.
Add the headers for cache control as pilif suggested and you should have a working solution to your problem.
无论你做什么,都要小心客户端的缓存:
浏览器会采取各种技巧来尝试最小化带宽,HTTP 协议中有很多方法可以做到这一点,所有这些都由 apache 处理 - 如果你只是提供本地文件。
如果您不这样做,那么这是您的责任。
至少看一下当前所有浏览器都支持的 ETag 和 If-Modified-Since 机制,它们似乎是查询服务器更新内容的最可靠的方法。
使用 If-Modified-Since-Header 向浏览器提供 CSS 文件的可能方法如下(空标头用于关闭 PHP 默认发送的任何非缓存标头):
代码将使用 if-modified-浏览器发送的since-header来检查服务器上的实际文件自浏览器给出的日期以来是否已更改。 如果是,则发送该文件,否则,将返回 304 Not Modified,并且浏览器不必重新下载整个内容(如果它足够智能,它也会将解析后的 CSS 保留在内存中)。
还有另一种机制涉及服务器为每段内容发送唯一的 ETag-Header。 客户端将使用 If-None-Match 标头将其发回,从而使服务器不仅可以决定上次修改的日期,还可以决定内容本身。
但这只会使代码变得更加复杂,所以我将其省略了。 FF、IE 和 Opera(可能还有 Safari)在收到附加了 Last-Modified 标头的内容时都会发送 If-Modified-Since 标头,因此效果很好。
另请记住,某些版本的 IE(或其使用的 JScript-Runtime)仍然在处理 GZIP 传输的内容时存在问题。
哦。 我知道这不是问题的一部分,但 Acrobat 在某些版本中也是如此。 我在使用 gzip 传输编码提供 PDF 时遇到过白屏的情况。
what ever you do, be careful about caching on the client side:
Browsers do all sort of tricks to try and minimize the bandwith and there are many ways in the HTTP protocol to do that, all of which are dealt with by apache - if you are just serving a local file.
If you are not, then it's your responsibility.
Have a look at least at the ETag and the If-Modified-Since mechanics which are supported by all current browsers and seem to be the most robust way to query the server for updated content.
A possible way to serve a CSS file to browsers using the If-Modified-Since-Header is something like this (the empty headers to turn off any non-caching headers PHP sends per default):
The code will use the if-modified-since-header the browser sends to check if the actual file on the server has changed since the date the browser has given. If so, the file is sent, otherwise, a 304 Not Modified is returned and the browser does not have to re-download the whole content (and if it's intelligent enough, it keeps the parsed CSS around in memory too).
There is another mechanic involving the server sending a unique ETag-Header for each piece of content. The Client will send that back using an If-None-Match header allowing the server to decide not only on the date of last modification but also on the content itself.
This just makes the code more complicated though, so I have left it out. FF, IE and Opera (probably Safari too) all send the If-Modified-Since header when they receive content with a Last-Modified header attached, so this works fine.
Also keep in mind that certain versions of IE (or the JScript-Runtime it uses) still have problems with GZIP-transferred content.
Oh. And I know that's not part of the question, but so does Acrobat in some versions. I've had cases and cases of white screens while serving PDFs with gzip transfer encoding.
您可以使用 mod_rewrite 试试运气。
创建一个脚本,通过例如
$_SERVER['QUERY_STRING']
将本地静态文件名作为输入,并以压缩形式输出。 许多提供商不允许使用.htaccess
文件配置mod_rewrite
或将其完全禁用。如果您之前没有使用过 rewrite,我推荐一本很好的初学者指南,例如 这个。
这样你就可以让 apache 将所有对静态文件的请求重定向到 php 脚本。 例如,style.css 将被重定向到 compress.php?style.css 。
与往常一样,对您接受的输入要极其谨慎,否则您就会遇到
XSS
漏洞!You can try your luck with mod_rewrite.
Create a script that takes a local static file name as input, through e.g.
$_SERVER['QUERY_STRING']
and outputs it in compressed form. Many providers don't allow configuringmod_rewrite
with.htaccess
files or have it completely disabled though.If you haven't used rewrite before, I recommend a good beginner's guide, like probably this one.
This way you can make the apache redirect all requests for a static file to a php script. style.css will be redirected to compress.php?style.css for instance.
As always be extremely cautious on the input you accept or you have an
XSS
exploit on your hands!您可以提前对 CSS 和 JavaScript 文件进行 gzip,而不是在用户请求 CSS 和 JavaScript 文件时动态进行 gzip。 只要 Apache 为他们提供正确的标头,您就是黄金。
例如,在 Mac OS X 上,在命令行上对文件进行 gzip 压缩就像这样简单:
但可能不是适合您的工作流程。
Instead of gzipping on the fly when users request the CSS and JavaScript files, you could gzip them ahead of time. As long as Apache serves them with the right headers, you’re golden.
For example, on Mac OS X, gzipping a file on the command line is as easy as:
Might not be the sort of workflow that works for you though.