【问题标题】:How to get 304 response for PHP generated javascript file?如何获得 PHP 生成的 javascript 文件的 304 响应?
【发布时间】:2012-12-07 21:07:52
【问题描述】:

我有以下 PHP 文件:

<?php

Header('Content-Type: application/javascript');

echo "// Some dynamically generated JavaScript here...";

所以它是一个 .php 文件,但它被解释为一个 JavaScript 文件。我会将它加载到这样的网页中:

<script type='text/javascript' src='myjavascript.php'></script>

我的问题是关于访问此文件时发送的 HTTP 代码。每次我请求此文件(直接或通过请求它的网页)时,Chrome 开发工具都会显示 200 OK 的状态。即使内容没有改变,也绝不是 304。

在内容没有改变的情况下,像这样动态生成的文件是否可以得到 304 Not Modified?如果不是,为什么?

我还使用了一些允许路由的 PHP 框架,例如:/js/myjavascript.js。所以我可以把上面的代码放在那个路由中,以同样的方式动态生成 JavaScript。但同样,每次仍然是 200,即使内容没有改变并且 URI 是一个 .js 文件。

有解决办法吗?在我的情况下,这个 javascript/php 文件的内容大约每天更改一次。所以我需要我的访问者浏览器大部分时间缓存文件(304 未修改),但当它确实发生变化时,我需要他们的浏览器下载并缓存新版本(200 OK)。

【问题讨论】:

  • 仅供参考,这个问题与您正在生成 JavaScript 的事实无关,特别是。我之前在 StackOverflow 上看到过这个问题的一般页面......目前无法找到它,但如果您搜索从 PHP 创建适当的可缓存响应,您可能会有更好的运气。
  • check out these,他们可能有你要找的东西。

标签: php apache browser browser-cache http-status-code-304


【解决方案1】:

只有当客户端在请求中包含If-Modified-Since 标头时,才应发送304 Not Modified 标头。

我有一个 PHP 脚本,它始终生成相同的一致输出(它恰好是图像/png),具体取决于重写规则提供给它的选项。对于我的脚本,我假设 ANY If-Modified-Since 反映了浏览器中的有效缓存数据,因此我的脚本包括:

// If they've got it, they should use it.
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strlen($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
    header("HTTP/1.0 304 Not Modified");
    exit;
}

如果您想在这方面更聪明,您可以解析变量并将其与对您的脚本重要的任何内容进行比较。您需要考虑如何在每次运行时动态生成内容的 PHP 脚本上下文中检测内容是否发生变化

有关浏览器缓存如何在 PHP 中工作的更多信息,请查看 this comment on PHP: header

您可以在命令行中使用cURL 测试此行为:

[ghoti@pc ~]$ curl -sL -w "%{http_code} %{url_effective}\\n" https://www.google.com/images/srpr/logo3w.png -o /dev/null
200 https://www.google.com/images/srpr/logo3w.png
[ghoti@pc ~]$ curl -H"If-Modified-Since: Sat, 31 Dec 2011 00:00:00 GMT" -sL -w "%{http_code} %{url_effective}\\n" https://www.google.com/images/srpr/logo3w.png -o /dev/null
200 https://www.google.com/images/srpr/logo3w.png
[ghoti@pc ~]$ curl -H"If-Modified-Since: Mon, 31 Dec 2012 00:00:00 GMT" -sL -w "%{http_code} %{url_effective}\\n" https://www.google.com/images/srpr/logo3w.png -o /dev/null
304 https://www.google.com/images/srpr/logo3w.png
[ghoti@pc ~]$ 

注意不同的日期。

如果您认为 Chrome 发送的标头不足,您可以尝试复制其他流行网站以标头方式提供的内容:

[ghoti@pc ~]$ curl -H"If-Modified-Since: Mon, 31 Dec 2012 00:00:00 GMT" -sLI https://www.google.com/images/srpr/logo3w.png
HTTP/1.1 304 Not Modified
Date: Wed, 05 Dec 2012 17:40:52 GMT
Expires: Thu, 13 Dec 2012 17:40:52 GMT
Age: 241012
Server: GFE/2.0

毫无疑问,Server: 可以忽略不计,但如果您包括其他三个,您可能会减少来自 Chrome 的投诉。不过,正如我所说,您将不得不提出您想要使用的标准来确定您认为动态生成的内容的“年龄”,因为 Apache 检测到的静态文件上的文件系统时间戳不再可用。

【讨论】:

  • 有趣...但是如果我发送该 304 标头然后 exit(),Chrome 开发工具将状态显示为“已取消”,“内容类型”显示为“待定”。而且文字是红色的,表示有错误什么的。为什么这与其他非生成文件的正常 304 不同?此外,在服务器端,检测内容是否实际改变也不是问题。在我的情况下非常简单。
  • Chrome 可能会在收到 304 时看到 Last-Modified: 标头。我不需要在 Firefox 中执行此操作,因此我没有测试。我很懒,但你显然不是。 ;-) 告诉我们进展如何!
  • @Jakobud - 我在这个答案中添加了最后一点,显示哪些响应标头来自已知良好的站点。也许如果你模仿那些,你就不会出错。请务必告诉我们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-23
  • 1970-01-01
  • 2015-07-16
  • 2011-01-29
  • 2012-11-06
  • 1970-01-01
  • 2014-11-27
相关资源
最近更新 更多