46

如何让 Apache 上的静态内容{被浏览器缓存}而不是{检查新鲜度{每个请求}}?

我正在开发托管在 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。

4

4 回答 4

62

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™!

于 2009-01-15T14:53:25.507 回答
29

使用该filesMatch指令,而不是ExpiresByType,您可以Content-Type通过匹配subtype(例如image/*)进行分组,而不是列出每一type/subtype对,而不是subtype(例如image/jpeg, 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>

根据这篇 Google 文章,我将过期时间设为不超过 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>
于 2012-04-05T18:57:11.740 回答
3

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

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

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

这里有一个简单的设置介绍,以及维基百科上的其他可能有用的回复列表

于 2009-01-15T14:57:55.450 回答
2

关于 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 都可以正常工作。

于 2011-07-09T18:05:32.043 回答