PHP动态文件缓存问题

发布于 2024-12-05 04:41:39 字数 2688 浏览 2 评论 0原文

我有一些由 PHP 在我的 .htaccess 中动态生成的 CSS 和 JS 文件:

AddHandler application/x-httpd-php .css .js

然后在文件内部,例如:

<?PHP if ($Browser == 'msie') { ?>
.bind('selectstart', function(event) { [...] })
<?PHP } ?>

在它们的顶部(第一行)我使用基于 Last-Modified 标头的条件获取,像这样:

<?PHP if (FileIsCached(getlastmod())) die(); ?>

这是功能:

public static function FileIsCached($Timestamp)
{
    $LastModified = substr(date('r', $Timestamp), 0, -5).'GMT';
    $IfModifiedSince = (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false);

    if (($Semicolon = strrpos($IfModifiedSince, ';')) !== false)
        $IfModifiedSince = substr($IfModifiedSince, 0, $Semicolon);

    header('Last-Modified: '.$LastModified);

    if (!$IfModifiedSince || ($IfModifiedSince != $LastModified))
        return false;

    header('HTTP/1.1 304 Not Modified');

    return true;
}

我不需要检查编码,因为我在 php.ini 中使用自动 gzipping:

 output_handler = ob_gzhandler

我通常将它们放在我的 index.php 中,如下所示:

<script type="<?PHP echo $JavascriptMIME; ?>" src="/script.js"></script>

一切都像魅力一样...这是我的首先加载响应标头:

HTTP/1.1 200 OK
Date: Fri, 16 Sep 2011 21:21:51 GMT
Last-Modified: Fri, 16 Sep 2011 19:25:37 GMT
Content-Encoding: gzip
Vary: Accept-Encoding
Cache-Control: max-age=31536000, public
Expires: Sat, 15 Sep 2012 21:21:51 GMT
Content-Type: application/javascript
Content-Length: 6161
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive

这是我的缓存响应头:

HTTP/1.1 304 Not Modified
Date: Fri, 16 Sep 2011 21:24:39 GMT
Connection: Keep-Alive
Keep-Alive: timeout=5, max=100
Expires: Sat, 15 Sep 2012 21:24:39 GMT
Cache-Control: max-age=31536000, public
Vary: Accept-Encoding

问题是,有时 HTTP 数据似乎会被 gzip 压缩内容或类似内容弄乱。 Chrome 网络控制台有时会显示以下错误:“资源解释为其他,但传输时未定义 MIME 类型”。 Mozilla 有时会对 index.php 发出 2 个请求,或者尝试使用下载提示来下载它。有时,当我通常加载 7 个文件时,文件请求会在 5 个处停止,而最后下载的文件内容会变得混乱,例如:

���������ÿÿ���������HTTP/1.1 200 OK
Date: Fri, 16 Sep 2011 19:53:26 GMT
Server: Apache/2.2.17 (Win32) PHP/5.3.6
X-Powered-By: PHP/5.3.6
Cache-Control: must-revalidate, no-cache, no-store, private, public
Cache-Control: max-age=0, max-stale=0, post-check=0, pre-check=0
Expires: Wed, 11 Apr 1984 18:36:00 GMT
Expires: 0
Last-Modified: Fri, 16 Sep 2011 19:53:26 GMT
Pragma: no-cache
Content-Encoding: gzip
Vary: Accept-Encoding
Content-Type: application/javascript
Content-Length: 674
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
....

这可能是什么?

I have some CSS and JS files that are dynamically generated by PHP using this in my .htaccess:

AddHandler application/x-httpd-php .css .js

And then inside the files, for example:

<?PHP if ($Browser == 'msie') { ?>
.bind('selectstart', function(event) { [...] })
<?PHP } ?>

On the top of them (first line ) i use a conditional get based on Last-Modified header, like this:

<?PHP if (FileIsCached(getlastmod())) die(); ?>

This is the function:

public static function FileIsCached($Timestamp)
{
    $LastModified = substr(date('r', $Timestamp), 0, -5).'GMT';
    $IfModifiedSince = (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false);

    if (($Semicolon = strrpos($IfModifiedSince, ';')) !== false)
        $IfModifiedSince = substr($IfModifiedSince, 0, $Semicolon);

    header('Last-Modified: '.$LastModified);

    if (!$IfModifiedSince || ($IfModifiedSince != $LastModified))
        return false;

    header('HTTP/1.1 304 Not Modified');

    return true;
}

I don't need to check encoding because I use automatic gzipping inside my php.ini:

 output_handler = ob_gzhandler

I put them normally inside my index.php like this:

<script type="<?PHP echo $JavascriptMIME; ?>" src="/script.js"></script>

Everything works like a charm... this is my first load response header:

HTTP/1.1 200 OK
Date: Fri, 16 Sep 2011 21:21:51 GMT
Last-Modified: Fri, 16 Sep 2011 19:25:37 GMT
Content-Encoding: gzip
Vary: Accept-Encoding
Cache-Control: max-age=31536000, public
Expires: Sat, 15 Sep 2012 21:21:51 GMT
Content-Type: application/javascript
Content-Length: 6161
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive

This is my cached response header:

HTTP/1.1 304 Not Modified
Date: Fri, 16 Sep 2011 21:24:39 GMT
Connection: Keep-Alive
Keep-Alive: timeout=5, max=100
Expires: Sat, 15 Sep 2012 21:24:39 GMT
Cache-Control: max-age=31536000, public
Vary: Accept-Encoding

The problem is that sometimes HTTP data seems to get messed up, maybe by gzipped content or something similar. Chrome network console sometimes show the following error: "Resource interpreted as Other but transferred with MIME type undefined". Mozilla sometimes makes 2 requests for index.php or try to download it with download prompt. Sometimes file requests stop at 5 when I normally load 7 files and the last downloaded file content is messed up like:

���������ÿÿ���������HTTP/1.1 200 OK
Date: Fri, 16 Sep 2011 19:53:26 GMT
Server: Apache/2.2.17 (Win32) PHP/5.3.6
X-Powered-By: PHP/5.3.6
Cache-Control: must-revalidate, no-cache, no-store, private, public
Cache-Control: max-age=0, max-stale=0, post-check=0, pre-check=0
Expires: Wed, 11 Apr 1984 18:36:00 GMT
Expires: 0
Last-Modified: Fri, 16 Sep 2011 19:53:26 GMT
Pragma: no-cache
Content-Encoding: gzip
Vary: Accept-Encoding
Content-Type: application/javascript
Content-Length: 674
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
....

What can it be?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

戏蝶舞 2024-12-12 04:41:40

尝试在 PHP 中关闭输出处理程序并查看是否正常工作。

我在 php 手册页上找到了 此评论可能你遇到了什么。

您可以尝试一下,如果这是问题所在,请使用 Apache 的 SetOutputFilter 通过将以下内容添加到 httpd.conf 来 gzip 内容,而不是让 PHP 执行此操作

<Location />
# Insert filter
SetOutputFilter DEFLATE

# Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html

# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip

# MSIE masquerades as Netscape, but it is fine
# BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

# NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
# the above regex won't work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html

# Don't compress images
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary

# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</Location>

Try turning the output handler off in PHP and see if things work correctly.

I found this comment on the php manual page that is probably what you are running into.

You could try that and if it is the problem, use Apache's SetOutputFilter to gzip the content for you by adding the following to httpd.conf instead of having PHP doing it

<Location />
# Insert filter
SetOutputFilter DEFLATE

# Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html

# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip

# MSIE masquerades as Netscape, but it is fine
# BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

# NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
# the above regex won't work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html

# Don't compress images
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary

# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</Location>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文