0

I have a PHP file get_css.php which generates CSS code more than 60 KB long. This code does not change very often. I want this code to be cached in user's browser. Now, when i visit a HTML page several times which includes get_css.php url to fetch css, my browser is loading all CSS contents from the server each time i visit the page.

Browsers should get the contents from server only if the CSS code is changed on server side. If the css code is not changed, browser will use the css code from the browser cache. I cannot use any PHP function which is not allowed in Server Safe Mode.

Is it possible? How can i achieve this?

4

4 回答 4

1

您无法通过 PHP 控制浏览器行为,但您可以使用 HTTP 代码告诉浏览器一些事情。

如果 CSS 没有改变,只需回复一个304 Not Modified响应代码:

if ($css_has_not_changed && $browser_has_a_copy) {
    http_response_code(304);
} else {
    // regenerate CSS
}

这样,浏览器请求文档(您无法控制),但您告诉他使用缓存的副本。

当然,这需要测试,因为我现在知道它在“第一次”浏览器请求文件时如何工作(也许请求标头可以告诉你更多信息)。一个快速的萤火虫测试表明,FirefoxCache-Control: no-cache在请求新副本时请求,并且Cache-Control: max-age=0当它有缓存时。

于 2012-11-22T08:35:18.977 回答
1

您不能如此轻易地强制客户端重新验证其缓存。

将变量查询字符串设置为其资源不会很好地与代理一起使用,但对于浏览器来说似乎就足够了。如果查询字符串发生更改,浏览器确实倾向于仅重新下载 css 文件。

 <link rel="stylesheet" type="text/css" href="/get_css.php?v=1.2.3"> 

潜在地,您可以使用 CSS 的命名,例如添加数字,但这不是一个很好的选择。

于 2012-11-22T07:54:31.317 回答
0

当你像这样包含 get_css.php 时添加普通的 GET 参数

<link rel="stylesheet" type="text/css" href="get_css.php?v=1">

浏览器会认为它是新链接并再次加载它。

并在 get_css.php 中使用它来制作浏览器缓存数据

<?php
header("Content-type: text/css");
header('Cache-Control: public');
header('Expires: ' . gmdate('D, d M Y H:i:s', strtotime('+1 year')) . ' GMT');
ob_start("ob_gzhandler");

//echo css here
于 2012-11-22T07:40:00.010 回答
0

默认情况下,浏览器希望缓存您的文档,但您必须为其提供足够的信息才能使其成为可能。一种相当简单的方法是发送Last-Modified标题,其中包含上次更改脚本的日期/时间。您还需要正确处理浏览器的“重新验证”请求,方法是检查传入Last-Modified日期,将其与脚本的实际修改日期进行比较304 Not Modified,如果文件未更改,则返回响应(带有空响应正文)。

确保您的服务器不会“神奇地”发送任何其他“无缓存”指令也是一个好主意。最简单的方法是发送一个Cache-Control指令,告诉浏览器你期望什么行为。

以下是每个Cache-Control选项的快速说明。

像下面这样的东西应该可以解决问题:

<?php
// this must be at the top of your file, no content can be output before it

$modified = filemtime(__FILE__);
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
  $if_modified_since=strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]);
  if( $modified > $if_modified_since ) {
    header('HTTP/1.0 304 Not Modified');
    exit();
  }
}
header('Cache-Control: must-revalidate');
header('Last-Modified: '.date("r",$modified));

// ... and the rest of your file goes here...

上面的示例很大程度上基于示例,并且可以在此处找到文章。

于 2012-11-22T15:29:33.507 回答