我的响应头中为什么会添加"Pragma:no-cache"?(Apache,PHP)

34

我继承了一个维护不良的网站,需要进行大量的清理工作。
其中之一就是改善性能。除此之外,我还会给图像添加Expires头信息。

现在,有些图像是通过PHP文件提供的,我发现它们确实有Expires头信息,但每次加载时也会重新下载。

查看响应头,我看到:

Expires Wed, 15 Jun 2011 18:11:55 GMT
Cache-Control   no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma  no-cache

显然这解释了问题。

我已经仔细查看了整个代码库,但没有找到任何地方有 "pragma" 这样的字眼。.htaccess 似乎也没有相关的信息。

有什么想法可以设置那些 "pragma"(和 "cache-control")头,并且我如何避免它?


运行 grep -R pragma . 命令来查找文件。 - mcandre
7个回答

31

问题可能出在php.ini文件中的session.cache_limiter=nocache设置上。将该值更改为空或public,以避免反缓存头。


谢谢! 我把session.cache_limiter('nocache')的默认值改成了'',解决了问题。 - Yeroon
“公开”对于一个拥有一些私人页面的网站来说,这不会很危险吗? - Alexis Wilke
据推测,这将限制缓存仅针对公共文档。 - technomage

13

我遇到了类似的问题,出现了 Pragma: nocache

session_cache_limiter(false); 在执行 session_start(); 之前似乎可以抑制这个问题。


10

创建一个简单的文件,不包含任何PHP库,但与通过PHP文件提供图像的文件位于同一个文件夹中。

file: test.php

通过浏览器请求该文件并检查标头。 如果您看到不想要的响应标头,则知道它们是通过Apache配置的,而不是通过PHP文件生成的,并且可以将搜索集中在目录树中的.htaccess文件和http.confg以及其他包含的Apache配置文件上。您将想要搜索:

<Directory....

并且

<VirtualHost

这些可能适用于您的网站的部分。

如果在请求该简单PHP文件时看不到头信息,则说明PHP在某处设置了头信息。在您的图像服务文件末尾(或在其显示图像并退出后),添加以下PHP片段:

var_dump(get_included_files());

通过图片服务的URL请求一张图片。以上代码片段将打印出该请求中使用的所有PHP文件。(您可能需要查看源代码或使用curl来查看原始输出,因为浏览器会报告无效的图片)

拥有一个用于工作的文件子集,可以在其中搜索调用的内容。

header();

函数。我认为header函数是原始PHP代码设置响应头的唯一方法。你还需要搜索

call_user_func
eval
$$

假如页面上有任何动态代码,使用PHP元编程能力来调用header函数。

祝你好运!


哇,非常感谢你详细的答案。这明显是Apache的配置问题,但我无权访问它。我只能通过FTP访问我的网站目录。你有什么主意可以使用我的.htaccess文件来覆盖/删除这些标头吗? - Daniel Magliola
很遗憾,这个问题太笼统了,无法快速给出答案。你需要知道哪些Apache指令导致了缓存,并覆盖其效果,还需要知道它们是否可以在.htaccess中被覆盖,并且知道如何使用语法进行操作。与其浪费太多时间,我会将此问题上报给服务器管理员,看看他们能否帮助你,因为“默认缓存”不是Apache和/或PHP模块的默认配置。#无法提供帮助,抱歉。 - Alana Storm
关于Apache2设置,您应该搜索所有文件。它可能隐藏在子目录中的某个文件中,而您不知道它在哪里...此外,搜索所有数据目录,因为您可能在任何级别上都有.htaccess文件。在我的情况下,它在/etc/apache2/conf-enabled/server-cgi-bin.conf中。 - Alexis Wilke

10
尝试在.htaccess文件中取消设置头部信息。以下示例将为扩展名为ico、jpeg、png、gif、js、css的所有文件取消设置头部信息:
<FilesMatch "\.(ico|jpeg|png|gif|js|css)$">
    Header unset Cache-Control
    Header unset Pragma
</FilesMatch>

您可以在这篇文章中找到一些提示。


4
我使用以下代码在运行时完成此操作:

header("Pragma:");

这迫使脚本取消Pragma头。


1
如果不在.htaccess文件中,它可能在主Apache配置文件中,或者根据设置在其中的某个包含文件中。

有什么办法可以从我的 .htaccess 文件中覆盖它吗?(我没有此服务器的SSH访问权限或httpd.conf访问权限) - Daniel Magliola
不确定如何删除标题 - 可以在Serverfault上询问。 - Colonel Sponsz

0
值得注意的是,对于遇到类似问题的人来说,许多框架都会自动添加头部信息,特别是缓存相关的头部信息。在框架库或应用程序内部很容易重载它们。

有没有任何下投票的原因?我知道Zend会自动添加头信息。这些头信息可以通过PHP的header标签进行重载,就像Michael所展示的那样,或者框架将有其特定的函数来执行此操作。对于Zend,您必须使用setHeader()。 - twunde

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