【问题标题】:Why do images served from my web server not cache on the client?为什么从我的 Web 服务器提供的图像没有缓存在客户端上?
【发布时间】:2009-06-03 22:37:39
【问题描述】:

我将所有图片都存储在 webroot 后面(/var/www/ 之前),这意味着 web 服务器无法为我的图片发回缓存标头。我需要添加什么才能使用户的网络缓存正常工作?目前,每次都被同一个浏览器点击。

我页面上的<img> 路径如下所示:

<img src="pic.php?u=1134&i=13513&s=0">

编辑:会不会是因为“pic.php?u=1134&amp;i=13513&amp;s=0”不是一个有效的文件名之类的?

// pic.php
<?php

    // open the file in a binary mode
    $user = $_GET['u'];
    $id = $_GET['i'];
    $s = $_GET['s'];

    if (!isset($user) && !isset($s) && $isset($id))
    {
        // display a lock!
        exit(0);
    }

    require_once("bootstrap_minimal.php"); //setup db connection, etc

    // does this image_id belong to the user?
    $stmt = $db->query('SELECT image_id, user_id, file_name, private FROM images WHERE image_id = ?', $id);
    $obj = $stmt->fetchObject();

    if (is_object($obj))
    {
        // is the picture is the users?
        if ($obj->user_id != $_SESSION['user_id'])
        {
            // is this a private picture?
            if ($obj->private == 1)
            {
                // check permissions...
                // display a lock in needed!
            }
        }
    }
    else
    {
        // display a error pic?!
        exit(0);
    }

    if ($s == 0)
    {
        $picture = $common->getImagePathThumb($obj->file_name);
    }
    else
    {
        $picture = $common->getImagePath($obj->file_name);
    }

    // send the right headers
    header("Content-Type: image/png");
    header("Content-Length: " . filesize($picture));

    $fp = fopen($picture, 'rb');

    // dump the picture and stop the script
    fpassthru($fp);
    exit;
?>

【问题讨论】:

    标签: php apache caching


    【解决方案1】:

    您需要添加如下内容:

    $expiry = 3600*24*7; // A week
    header('Expires: ' . gmdate('D, d M Y H:i:s' time() + $expiry) . ' GMT');
    header('Cache-control: private, max-age=' . $expiry);
    

    【讨论】:

    • 看起来图像在某些身份验证后受到保护,因此 Cache-control 标头需要指定私有缓存;没有公共存储空间。
    • 在“GMT”之后缺少一个“)”。太棒了,TY!
    • 还有 Rob,我将 'public' 更改为 'private'
    【解决方案2】:

    Apache 默认只缓存静态文件。您需要通过header() 函数发送缓存控制标头。 This article有很多关于这个话题的信息。

    或者,您可以使用 PHP 文件重定向到图像的实际位置。 (如果您对标头一无所知,这可能是最简单的方法。)

    【讨论】:

    • 如果图像不在文档根目录或合适的别名下,则重定向到图像位置是没有用的,这也违背了将其置于身份验证检查之后的目的。
    • 这只是我扔在那里的另一种选择。如果它不适用于您的设置,请不要使用它。我不明白为什么我因此而被否决。
    【解决方案3】:

    你可以试试:

    header("Cache-Control: max-age=3600");
    

    这应该在文件上发送一小时的缓存超时。

    【讨论】:

      【解决方案4】:

      在您的情况下,我会做的是使用 .php 文件流式传输图像的字节。不要直接链接到图片;相反,链接到一个 php 文件: - 输出缓存头 - 从 webroot 后面从磁盘读取文件 - 将图像位发送到网络

      【讨论】:

        【解决方案5】:

        简单的答案:您没有告诉用户的浏览器缓存它

        【讨论】:

          猜你喜欢
          • 2011-03-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多