使用 Apache 缓存网站图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/447014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Website image caching with Apache
提问by Piskvor left the building
How can I get static content on Apache to be {cached by browser} and not {checked for freshness {with every request}}?
我怎样才能让 Apache 上的静态内容{被浏览器缓存}而不是{检查新鲜度{每个请求}}?
I'm working on a website hosted on Apache webserver. Recently, I was testing something with headers (Content-Type for different types of content) and saw a lot of conditional requests for images. Example:
我正在开发一个托管在 Apache 网络服务器上的网站。最近,我正在测试一些带有标题的东西(不同类型内容的 Content-Type),看到了很多对图像的条件请求。例子:
200 /index.php?page=1234&action=list
304 /favicon.ico
304 /img/logo.png
304 /img/arrow.png
(etc.)
Although the image files are static content and are cached by the browser, every time an user opens a page that links to them, they are conditionally requested, to which they send "304 Not Modified". That's good (less data transferred), but it means 20+ more requests with every page load (longer page load due to all those round-trips, even with Keep-Alive and pipelining enabled).
尽管图像文件是静态内容并由浏览器缓存,但每次用户打开链接到它们的页面时,都会有条件地请求它们,并向其发送“304 Not Modified”。这很好(传输的数据更少),但这意味着每次加载页面都会有 20 多个请求(由于所有这些往返,页面加载时间更长,即使启用了 Keep-Alive 和流水线)。
How do I tell the browser to keep the existing file and not check for newer version?
如何告诉浏览器保留现有文件而不检查更新版本?
EDIT: the mod_expires method works, even with the favicon.
编辑: mod_expires 方法有效,即使使用 favicon 也是如此。
回答by Piskvor left the building
Expiresmodule in Apache solves this
Apache 中的Expires模块解决了这个问题
a2enmod expires
it needs to be loaded in server config, and set up in .htaccess(or in server config).
它需要在服务器配置中加载,并在.htaccess(或在服务器配置中)进行设置。
With an Expiresheader, the resource is only requested the first time. Before the expiration date, subsequent requests are fulfilled from browser cache. After the specified time expires and the resource is needed, only then it is requested again (conditionally - a 304 will be returned for an unchanged resource). The only reliable way to clear it from the cache before it expires is manually, or by forcing a refresh (usually Ctrl-F5). (This could be an issue if the resource changes in the meantime, but statical images don't change very often.)
使用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"
For favicon.ico, a bit more work is needed (Apache normally does not recognize Windows icon files, and sends this as the default text/plain).
对于 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"
And voila, It Works?!
瞧,它有效吗?!
回答by Marco Demaio
With the filesMatchdirective, instead of ExpiresByType, you can group Content-Typeby matching subtype(e.g. image/*), instead of listing each type/subtypepair, not subtype(e.g image/jpeg, image/png).
使用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>
Acoording to this Google articleI made expiration not longer than 1 year (access plus 11 month) and added Cache-Control "public"to enable HTTPS caching for Firefox.
根据这篇 Google 文章,我将过期时间设置为不超过 1 年 ( access plus 11 month) 并添加Cache-Control "public"以启用 Firefox 的 HTTPS 缓存。
For CSS and JS, Google recommends an expiry period of 1 week.
对于 CSS 和 JS,Google 建议的有效期为 1 周。
<filesMatch "\.(css|js)$">
ExpiresActive On
ExpiresDefault "access plus 1 week"
Header append Cache-Control "public"
</filesMatch>
回答by ConroyP
If you set the Expiresheader on your http response for your static images, your server won't be checked again for that image after first download until the time specified has passed, e.g. if I download a file from your server now that gives it's Expiresheader as
如果您Expires在静态图像的 http 响应中设置标头,则在第一次下载后,在指定的时间过去之前不会再次检查该图像的服务器,例如,如果我现在从您的服务器下载一个文件,该文件的Expires标头为
Expires: Fri, 1 Jan 2010 00:00:01 GMT
then my browser won't look for it from your server again until 2010, unless I clear my cache/do a force refresh (Ctrl+F5 on windows).
那么我的浏览器直到 2010 年才会再次从您的服务器中查找它,除非我清除缓存/强制刷新(在 Windows 上为 Ctrl+F5)。
There's a simple introduction to setting this up here, and a list of other possibly helpful responses over at wikipedia
回答by Anon
Regarding favicon.ico, put it in your server document root say /var/www/html and add this to /etc/httpd/conf/httpd.conf in the Aliases section:-
关于 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>
Then a single favicon.ico will work for all the virtual hosted sites since you are aliasing it. After a user visits your site, any further visits will draw on the browser cache copy for one month, and not from the web.
然后一个 favicon.ico 将适用于所有虚拟托管站点,因为您将其别名化。用户访问您的网站后,任何进一步访问都将在一个月内使用浏览器缓存副本,而不是来自网络。
I Could not get
我无法得到
ExpiresByType image/ico "access plus 1 month"
to work at all. Maybe it needs to be type text/plain as suggested above. In any case ExpiresDefault works OK.
工作。也许它需要按照上面的建议输入 text/plain。在任何情况下 ExpiresDefault 都可以正常工作。

