利用浏览器缓存,如何使用 apache 或 .htaccess?

Posted

技术标签:

【中文标题】利用浏览器缓存,如何使用 apache 或 .htaccess?【英文标题】:Leverage browser caching, how on apache or .htaccess? 【发布时间】:2011-10-16 05:53:06 【问题描述】:

在这里做什么?我有一大堆 Google Speed Page 对“利用浏览器缓存”说的文件。但我不知道怎么做?我是否会弄乱或更改 Apache 配置文件(如下),还是在我的 .htaccess 页面中添加一些内容?

 <IfModule mod_proxy.c>
        ProxyRequests Off
        CacheRoot "/var/run/proxy"
        CacheSize 1024
        CacheGcInterval 24
    #CacheMaxExpire 24
    #CacheLastModifiedFactor 0.1
    #CacheDefaultExpire 1
    #NoCache a_domain.com another_domain.edu joes.garage_sale.com
        <Directory "disabled_proxy">
            Allow from example.com
            Deny from all
            Order Deny,Allow
        </Directory>
    </IfModule>
    ##
    #### mod_expires is configured so that all static files but images
    #### expire after 60 seconds. Any response that has a life span of more
    #### than 5 seconds (see webperfcache.conf) will be cached by webperfcache.
    #### Make sure your CGIs return a "Cache-Control: no-cache" header if you
    #### elect to make your dynamically generated html pages not cache-able.
    #### If all your HTML pages are static you may also increase ExpiresDefault.

    <IfModule mod_expires.c>
        ExpiresActive On
        ExpiresDefault A60
        ExpiresByType image/bmp A3600
        ExpiresByType image/gif A3600
        ExpiresByType image/ief A3600
        ExpiresByType image/jpeg A3600
        ExpiresByType image/png A3600
        ExpiresByType image/tiff A3600
        ExpiresByType image/x-cmu-raster A3600
        ExpiresByType image/x-portable-anymap A3600
        ExpiresByType image/x-portable-bitmap A3600
        ExpiresByType image/x-portable-graymap A3600
        ExpiresByType image/x-portable-pixmap A3600
        ExpiresByType image/x-rgb  A3600
        ExpiresByType image/x-xbitmap A3600
        ExpiresByType image/x-xpixmap A3600
        ExpiresByType image/x-xwindowdump A3600
        ExpiresByType audio/basic A3600
        ExpiresByType audio/midi A3600
        ExpiresByType audio/mpeg A3600
        ExpiresByType audio/x-aiff A3600
        ExpiresByType audio/x-pn-realaudio A3600
        ExpiresByType audio/x-pn-realaudio-plugin A3600
        ExpiresByType audio/x-realaudio A3600
        ExpiresByType audio/x-wav A3600
        ExpiresByType video/mpeg A3600
        ExpiresByType video/quicktime A3600
        ExpiresByType video/x-msvideo A3600
        ExpiresByType video/x-sgi-movie A3600
    </IfModule>

【问题讨论】:

【参考方案1】:

我借此机会提供了完整的.htaccess 代码以传递 Google PageSpeed Insight:

    启用压缩 利用浏览器缓存
# Enable Compression
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/rss+xml
  AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
  AddOutputFilterByType DEFLATE application/x-font
  AddOutputFilterByType DEFLATE application/x-font-opentype
  AddOutputFilterByType DEFLATE application/x-font-otf
  AddOutputFilterByType DEFLATE application/x-font-truetype
  AddOutputFilterByType DEFLATE application/x-font-ttf
  AddOutputFilterByType DEFLATE application/x-javascript
  AddOutputFilterByType DEFLATE application/xhtml+xml
  AddOutputFilterByType DEFLATE application/xml
  AddOutputFilterByType DEFLATE font/opentype
  AddOutputFilterByType DEFLATE font/otf
  AddOutputFilterByType DEFLATE font/ttf
  AddOutputFilterByType DEFLATE image/svg+xml
  AddOutputFilterByType DEFLATE image/x-icon
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/javascript
  AddOutputFilterByType DEFLATE text/plain
</IfModule>
<IfModule mod_gzip.c>
  mod_gzip_on Yes
  mod_gzip_dechunk Yes
  mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
  mod_gzip_item_include handler ^cgi-script$
  mod_gzip_item_include mime ^text/.*
  mod_gzip_item_include mime ^application/x-javascript.*
  mod_gzip_item_exclude mime ^image/.*
  mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</IfModule>

# Leverage Browser Caching
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/jpg "access 1 year"
  ExpiresByType image/jpeg "access 1 year"
  ExpiresByType image/gif "access 1 year"
  ExpiresByType image/png "access 1 year"
  ExpiresByType text/css "access 1 month"
  ExpiresByType text/html "access 1 month"
  ExpiresByType application/pdf "access 1 month"
  ExpiresByType text/x-javascript "access 1 month"
  ExpiresByType application/x-shockwave-flash "access 1 month"
  ExpiresByType image/x-icon "access 1 year"
  ExpiresDefault "access 1 month"
</IfModule>
<IfModule mod_headers.c>
  <filesmatch "\.(ico|flv|jpg|jpeg|png|gif|css|swf)$">
  Header set Cache-Control "max-age=2678400, public"
  </filesmatch>
  <filesmatch "\.(html|htm)$">
  Header set Cache-Control "max-age=7200, private, must-revalidate"
  </filesmatch>
  <filesmatch "\.(pdf)$">
  Header set Cache-Control "max-age=86400, public"
  </filesmatch>
  <filesmatch "\.(js)$">
  Header set Cache-Control "max-age=2678400, private"
  </filesmatch>
</IfModule>

还有一些针对各种 Web 服务器的配置,请参阅here。 希望这将有助于获得 100/100 的分数。

【讨论】:

我认为 mod_headers 和 mod_expires 用不同的选项做同样的事情,只应该使用一个。我错过了什么吗? 感谢分享@hyip gtmetrix 仍然向我展示了使用您的代码启用 gzip 压缩。对我来说,这适用于AddOutputFilterByType DEFLATE text/text text/html text/plain text/xml text/css application/x-javascript application/javascript 我认为 100/100 是一个神话! :) 对此表示祝贺。许多脚本(如 opencart 或 woocommerce)都存在 ExpiresDefault 配置问题。对这个有什么想法吗? 任何ExpiresDefault 都可以被标头集过期覆盖。观察.htaccess 层次结构以确保您的ExpiresDefault 没有在较低级别被覆盖【参考方案2】:

几天前我也在做同样的事情。将此添加到我的 .htaccess 文件中:

ExpiresActive On
ExpiresByType image/gif A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/png A2592000
ExpiresByType image/x-icon A2592000
ExpiresByType text/css A86400
ExpiresByType text/javascript A86400
ExpiresByType application/x-shockwave-flash A2592000
#
<FilesMatch "\.(gif¦jpe?g¦png¦ico¦css¦js¦swf)$">
Header set Cache-Control "public"
</FilesMatch>

现在,当我运行 google speed page 时,利用浏览器缓存不再是高优先级。

希望这会有所帮助。

【讨论】:

检查您的代码,我在使用您的代码时遇到了内部服务器错误 @Francesco 检查你的服务器,你是否启用了 mod_headers.c 和 mod_expires.c ? 我在 CakePHP 中遇到了类似的问题,但这并不是所有文件的解决方案:***.com/questions/18927604/… @Adam - 例如:我将 ExpiresByType image/jpg 设置为“访问 1 年”,这意味着直到一年我的所有网站 JPG 都将从缓存中加载,对吗?但是,如果我更改任何 JPG 文件,那么它会在我的网站中反映为新文件吗?或者它会从缓存中加载旧图像直到 1 年? @HelpingHands .. 是的,这是正确的。您可能想使用“访问加 1 年”,您还可以在“Header set Cache-Control”中添加更多设置,以更好地控制缓存/过期。【参考方案3】:

这是我用来控制标头/缓存的工具,我不是 Apache 专业人士,因此请告诉我是否有改进的余地,但我知道这在我的所有网站上运行良好已有一段时间了现在。

Mod_expires

http://httpd.apache.org/docs/2.2/mod/mod_expires.html

此模块控制服务器响应中的 Expires HTTP 标头和 Cache-Control HTTP 标头的 max-age 指令的设置。过期日期可以设置为相对于源文件最后一次修改的时间,或者相对于客户端访问的时间。

这些 HTTP 标头是对客户端的关于文档有效性和持久性的指示。如果已缓存,则在此时间过去之前,可能会从缓存中而不是从源中获取文档。之后,缓存副本被认为“过期”无效,必须从源获取新副本。

# BEGIN Expires
<ifModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 seconds"
ExpiresByType text/html "access plus 1 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 216000 seconds"
ExpiresByType application/x-javascript "access plus 216000 seconds"
</ifModule>
# END Expires

Mod_headers

http://httpd.apache.org/docs/2.2/mod/mod_headers.html

此模块提供指令来控制和修改 HTTP 请求和响应标头。标题可以合并、替换或删除。

# BEGIN Caching
<ifModule mod_headers.c>
<filesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$">
Header set Cache-Control "max-age=2592000, public"
</filesMatch>
<filesMatch "\.(css)$">
Header set Cache-Control "max-age=604800, public"
</filesMatch>
<filesMatch "\.(js)$">
Header set Cache-Control "max-age=216000, private"
</filesMatch>
<filesMatch "\.(xml|txt)$">
Header set Cache-Control "max-age=216000, public, must-revalidate"
</filesMatch>
<filesMatch "\.(html|htm|php)$">
Header set Cache-Control "max-age=1, private, must-revalidate"
</filesMatch>
</ifModule>
# END Caching

【讨论】:

别忘了启用 mod_headers 和 mod_expires,你可以通过运行 a2enmod rewritea2enmod headers 命令来启用 为什么在正则表达式中包含双斜杠 (\\....)?只使用一个是正确的,例如&lt;FilesMatch "\.(gif|jpe?g|png)$"&gt;(示例从FilesMatch docs逐字复制。 我不知道我为什么要这样做@QuinnComendant,感谢您了解这一点,我已经更新了帖子以反映正确的语法。似乎两者都可以正常工作,但始终是具有正确语法的最佳实践。【参考方案4】:

首先我们需要检查我们是否启用了 mod_headers.c 和 mod_expires.c。

sudo apache2 -l

如果我们没有,我们需要启用它们

sudo a2enmod headers

那我们需要重启apache

sudo apache2 restart

最后,在 .htaccess 上添加规则(见其他答案),例如

ExpiresActive On
ExpiresByType image/gif A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/png A2592000
ExpiresByType image/x-icon A2592000
ExpiresByType text/css A86400
ExpiresByType text/javascript A86400
ExpiresByType application/x-shockwave-flash A2592000
#
<FilesMatch "\.(gif|jpe?g|png|ico|css|js|swf)$">
Header set Cache-Control "public"
</FilesMatch>

【讨论】:

Header set Cache-Control "public" mayt be wrong show error 500

以上是关于利用浏览器缓存,如何使用 apache 或 .htaccess?的主要内容,如果未能解决你的问题,请参考以下文章

apache_conf 利用浏览器缓存

apache_conf 利用浏览器缓存

apache_conf 利用浏览器缓存

apache_conf 利用浏览器缓存

apache_conf 利用浏览器缓存

apache_conf htaccess:利用浏览器缓存的指令