【问题标题】:Website image caching with Apache使用 Apache 缓存网站图像
【发布时间】:2010-10-01 14:42:59
【问题描述】:

如何让 Apache 上的静态内容{被浏览器缓存}而不是{检查新鲜度 {with each request}}?

我正在开发一个托管在 Apache 网络服务器上的网站。最近,我正在测试一些带有标题的东西(Content-Type 用于不同类型的内容),并看到了很多对图像的条件请求。示例:

200 /index.php?page=1234&action=list
304 /favicon.ico
304 /img/logo.png
304 /img/arrow.png
(etc.)

虽然图像文件是静态内容并由浏览器缓存,但每次用户打开链接到它们的页面时,都会有条件地请求它们,并发送“304 Not Modified”。这很好(传输的数据更少),但这意味着每次页面加载都会产生 20 多个请求(由于所有这些往返行程导致页面加载时间更长,即使启用了 Keep-Alive 和流水线也是如此)。

如何告诉浏览器保留现有文件而不检查更新版本?

编辑: mod_expires 方法有效,即使使用 favicon。

【问题讨论】:

    标签: apache mod-expires image-caching


    【解决方案1】:

    Apache 中的Expires 模块解决了这个问题

    a2enmod expires
    

    需要在服务器配置中加载,并在.htaccess(或服务器配置)中设置。

    使用Expires 标头,仅在第一次请求资源。在到期日期之前,后续请求会从浏览器缓存中完成。在指定的时间到期并且需要资源后,才再次请求它(有条件 - 将返回 304 以获取未更改的资源)。在它过期之前从缓存中清除它的唯一可靠方法是手动或强制刷新(通常是 Ctrl-F5)。 (如果资源同时发生变化,这可能是个问题,但静态图像不会经常变化。)

    # enable the directives - assuming they're not enabled globally
    ExpiresActive on
    
    # send an Expires: header for each of these mimetypes (as defined by server)
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/jpeg "access plus 1 month"
    
    # css may change a bit sometimes, so define shorter expiration
    ExpiresByType text/css "access plus 1 days"
    

    对于 favicon.ico,需要做更多的工作(Apache 通常无法识别 Windows 图标文件,并将其作为默认文本/纯文本发送)。

    # special MIME type for icons - see http://www.iana.org/assignments/media-types/image/vnd.microsoft.icon
    AddType image/vnd.microsoft.icon .ico
    # now we have icon MIME type, we can use it
    # my favicon doesn't change much
    ExpiresByType image/vnd.microsoft.icon "access plus 3 months"
    

    瞧,It Works™!

    【讨论】:

    • 我已将我的网站图标指定为具有“image/x-icon”的 MIME 类型 - 我似乎无法让 Apache 在其上设置 Expires 标头。知道这是为什么吗?我需要使用 image/vnd.microsoft.icon 吗?
    • @Tom:“.ICO 文件的官方 IANA 注册 MIME 类型是 image/vnd.microsoft.icon。” (维基百科)所以,你不需要使用它,但它是正确的 MIME 类型——你会发送带有 JPEG 图像的“image/x-jpg”而不是标准的“image/jpeg”吗?您是否出于技术原因不想返回正确的 MIME 类型?
    • @Tom:关于第一个问题,服务器不应该关心 MIME 类型是什么,只要它知道。您是否有此 MIME 类型的 AddType before ExpiresByType?
    • 现在 .ico 上的缓存标头似乎设置正常 - 我想我在重新启动 Apache 后检查设置时一定没有正确清除浏览器缓存。我使用的是 ExpiresDefault 而不是 ExpiresByType。我已经开始使用 MIME 类型的 image/vnd.microsoft.icon - 感谢您提供的信息。起初似乎有点特定于供应商,但感谢您让我知道维基百科文章。
    • 还检查 http:权威指南第 7 章,7.83 服务器重新验证。图书链接amazon.com/HTTP-Definitive-Guide-David-Gourley/dp/1565925092
    【解决方案2】:

    使用filesMatch 指令,而不是ExpiresByType,您可以通过匹配subtype(例如image/*)对Content-Type 进行分组,而不是列出每个type/subtype 对,而不是列出subtype(例如@ 987654329@, image/png)。

    #Set caching on image files for 11 months
    <filesMatch "\.(ico|gif|jpg|png)$">
      ExpiresActive On
      ExpiresDefault "access plus 11 month"
      Header append Cache-Control "public"
    </filesMatch>
    

    根据this Google article,我将过期时间设置为不超过 1 年 (access plus 11 month) 并添加了Cache-Control "public" 以启用 Firefox 的 HTTPS 缓存。

    对于 CSS 和 JS,Google 建议有效期为 1 周。

    <filesMatch "\.(css|js)$">
      ExpiresActive On
      ExpiresDefault "access plus 1 week"
      Header append Cache-Control "public"
    </filesMatch>
    

    【讨论】:

    • 我非常喜欢这个答案。感谢分享!
    • 如果我需要 '' 检查嵌套指令是否可以?
    【解决方案3】:

    如果您在您的静态图像的 http 响应中设置 Expires 标头,则在第一次下载后,您的服务器将不会再次检查该图像,直到指定的时间过去,例如如果我现在从你的服务器下载一个文件,它的 Expires 标头为

    Expires: Fri, 1 Jan 2010 00:00:01 GMT 
    

    那么直到 2010 年,我的浏览器才会再次从您的服务器中查找它,除非我清除缓存/强制刷新(在 Windows 上按 Ctrl+F5)。

    here 有一个简单的设置介绍,wikipedia 上还有其他可能有用的回复列表

    【讨论】:

      【解决方案4】:

      关于 favicon.ico,将它放在您的服务器文档根目录中,例如 /var/www/html 并将其添加到别名部分的 /etc/httpd/conf/httpd.conf 中:-

      Alias /favicon.ico "/var/www/html/favicon.ico"
      <Directory "/var/www/html">
          <Files favicon.ico>
             ExpiresActive On
             ExpiresDefault "access plus 1 month"
          </Files>
      </Directory>
      

      然后,一个单一的 favicon.ico 将适用于所有虚拟托管站点,因为您正在为其设置别名。用户访问您的网站后,任何进一步的访问都将在一个月内使用浏览器缓存副本,而不是来自网络。

      我找不到

      ExpiresByType image/ico "access plus 1 month"
      

      完全可以工作。也许它需要像上面建议的那样输入 text/plain。在任何情况下,ExpiresDefault 都可以正常工作。

      【讨论】:

      • 如果您不介意所有网站都共享同​​一个图标,那么关于全球网站图标的观点很好。请参阅我对image/ico 的回答:1)image/ico 不是正确的 MIME 类型,2)您需要定义 image/vnd.microsoft.icon - 它不是由 Apache 预定义的。
      猜你喜欢
      • 1970-01-01
      • 2017-08-21
      • 1970-01-01
      • 2015-05-27
      • 2016-04-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-28
      • 1970-01-01
      相关资源
      最近更新 更多