如何在Apache httpd(MAMP)中防止HTTP文件缓存

154

我正在MAMP中开发一个单页面的Javascript应用程序。我的JavaScript和HTML模板文件在请求之间被缓存了。

是否有一种简单的方法可以在MAMP中指示我要防止http文件缓存?可能需要使用.htaccess文件吗?我应该将.htaccess文件放在哪里或者如何修改Mac上MAMP的虚拟主机?

5个回答

343

试过这个了吗?应该适用于.htaccesshttpd.confVirtualHost(通常放置在httpd-vhosts.conf中,如果您已从httpd.conf中包含它)。

<filesMatch "\.(html|htm|js|css)$">
  FileETag None
  <ifModule mod_headers.c>
     Header unset ETag
     Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
     Header set Pragma "no-cache"
     Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
  </ifModule>
</filesMatch>

100%防止文件被缓存

这类似于Google广告如何使用头部Cache-Control:private,x-gzip-ok =“”>来防止代理和客户端缓存广告。

来自http://www.askapache.com/htaccess/using-http-headers-with-htaccess.html

如果您在获取模板文件时使用的扩展名不是.html,可以选择添加该扩展名。


3
谢谢,这在 .htaccess 文件中非常有效。我可以在检查标头时看到缓存控制选项,并且我的文件在请求之间显示 http 200 而不是 304,正是我所需要的。 - dmck
2
不要忘记添加LoadModule命令。 LoadModule headers_module lib/modules/mod_headers.so - Spenhouet
1
@ThariqNugrohotomo 是的,这是可能的!这是一个正则表达式,你可以尝试 <filesMatch "\.+"> 或者 <filesMatch ^> - Charlie Rudenstål
似乎不起作用。如果我在服务器上更改文件并刷新页面,什么也不会发生,但是如果等待5分钟,它就会更改。有一种服务器端缓存,即使重新启动Apache后仍然存在。 - Aaron Franke
关于这个特殊的过期日期,请参见为什么WordPress将11 Jan 1984用作Expires头的防缓存值?,而在PHP中使用非常相似的日期,请参见为什么“Expires”是1981年? - Speravir
显示剩余2条评论

5
根据这个例子:http://drupal.org/node/550488,以下内容可能在 .htaccess 文件中可行。
 <IfModule mod_expires.c>
   # Enable expirations.
   ExpiresActive On

   # Cache all files for 2 weeks after access (A).
   ExpiresDefault A1209600

  <FilesMatch (\.js|\.html)$>
     ExpiresActive Off
  </FilesMatch>
 </IfModule>

不幸的是,当我在项目目录中放置一个 .htaccess 文件时,这并不起作用。我不确定 mod_expires 是否处于活动状态。 - dmck
5
@dmck:如果mod_expires未启用,则删除<IfModule mod_expires.c></IfModule>部分...这样,您将会收到一个错误而不是那些指令被静默忽略。 - Stennie
在项目目录中,任何微小的语法错误都可能导致500错误。 - SDsolar
这只是禁用这些文件的mod_expires。可能是服务器(或另一个模块)设置了这些标头。一般(任何服务器)解决方案需要确保这些标头被覆盖(使用mod_expires再次或使用mod_headers - 这也将覆盖mod_expires)。 - MrWhite

3

我以前也遇到了同样的问题,但是在这里找到了一个好的解决方法。

基本上是找到php.ini文件并注释掉OPCache行。希望这个替代方案也能帮助其他人。


4
这是关于服务器端PHP缓存,即OPCache的问题。问题涉及到浏览器缓存通过HTTP请求的文件。 - Flion

2
没有使用mod_expires模块,设置文件的过期头信息将变得更加困难。对于任何生成的内容,您可以在响应中设置一些默认头信息,以此来完成mod_expires的工作:
<?php header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + 3600)); ?>

以下内容翻译自Stack Overflow用户@brianegge的回答(该回答还介绍了mod_expires解决方案):

对于静态文件,比如JavaScript文件,此方法无效。由于浏览器与源文件之间只有Apache(没有任何过期模块),因此需要使用类似于?rd=45642111随机标记来避免缓存JavaScript文件,从而使url类似于:

<script type="texte/javascript" src="my/url/myjs.js?rd=4221159546">

如果页面上的这个url是由PHP文件生成的,您可以使用PHP简单地添加随机部分。通过简单地附加随机查询字符串参数来随机化url的方式是ajax jQuery请求设置no-cache的基础内容。浏览器永远不会认为两个具有不同查询字符串的url是相同的,并且永远不会使用缓存版本。
编辑
请注意,您还应该测试mod_headers。如果您有mod_headers,则可以使用Header关键字直接设置Expires标头。

谢谢,不幸的是我没有使用任何PHP文件。我会研究mod_headers和安装mod_expires。 - dmck
如何防止 CSS 文件缓存? - Aaron Franke

1
<FilesMatch "\.(js|css)$">
  ExpiresActive On
  ExpiresDefault A1
  Header append Cache-Control must-revalidate
</FilesMatch>

这不是一个好的答案质量。请尽量详细地解释一下解决OP报告的问题的步骤。 - leopal
为什么选择A1而不是A0或者甚至是M0,因为它们都是静态资源? - MrWhite

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接