php - 使用 URL 参数和 XSendFile 在浏览器中缓存图像

标签 php reactjs apache browser-cache x-sendfile

我正在尝试建立一个站点,以便用户只能访问他们自己的图像和音频文件。为此,我在 URL 中使用变量,例如:

 <img src="/public/get_file.php?type=image&file=pic001.png" />

在前端,我使用的是 React JS(不确定这对这个问题是否重要)。但在后端,PHP 脚本将验证用户是否已登录(仅通过检查一个简单的 SESSION 变量)并在用户的数据目录中查找该文件(基于其 SESSION 变量中的用户 ID)。如果存在,它将使用 XSendFile 将其返回给用户。

我遇到的问题是,每次用户尝试访问文件时,在加载文件之前都会有一点延迟。这告诉我它们可能没有被浏览器缓存。

为什么文件没有被缓存?是否与 URL 参数或 PHP/XSendFile 的使用有关?

我该怎么做才能缓存我的文件(图像/音频)?

更新

这里要求的是我的 get_file.php:

<?php

        session_start();

        if (empty($_SESSION['auth']['id'])){
                exit;
        }

        require_once("../../api_modules/settings.php");

        $developer_id = $_SESSION['auth']['id'];

        $type = preg_replace('/[^-a-zA-Z0-9_]/', '', $_GET['type']);
        $file = preg_replace('/[^-a-zA-Z0-9_\.]/', '', $_GET['file']);

        $file = preg_replace('/[\.]{2,}/', '', $file);

        $project_id = preg_replace('/[^0-9]/', '', $_GET['project_id']);
        $developer_id = preg_replace('/[^0-9]/', '', $developer_id);

        if ($type == "image")
                $file = FILEPATH ."files/$developer_id/$project_id/images/thumbs/88x88/$file";
        else if ($type == "full_image")
                $file = FILEPATH ."files/$developer_id/$project_id/images/originals/$file";
        else if ($type == "audio"){
                $file = FILEPATH ."files/$developer_id/$project_id/audio/$file";
        }
        else {
                exit;
        }


        header("X-Sendfile: $file");
        header("Content-type: application/octet-stream");
        header('Content-Disposition: attachment; filename="' . basename($file) . '"');

最佳答案

我认为这是一个 duplicate .

但由于有赏金,让我们尝试将您的代码与那里建议的解决方案一起调整。

您需要检查 Apache 是否启用了 mod_expires 和 mod_headers 并正常工作。

然后在开始实际输出之前检查文件是否被修改:

...
$last_modified_time = filemtime($file); 
$etag = md5_file($file);
// always send headers
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT"); 
header("Etag: $etag"); 
// exit if not modified
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time || 
    @trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) { 
    header("HTTP/1.1 304 Not Modified"); 
    exit; 
} else {
    header("X-Sendfile: $file");
    header("Content-type: application/octet-stream");
    header('Content-Disposition: attachment; filename="' . basename($file) . '"');
}

关于php - 使用 URL 参数和 XSendFile 在浏览器中缓存图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55090856/

相关文章:

php - 创建分类法时删除描述框

php - 过滤集合时删除键 laravel

node.js - 如何导入同名的 Node 模块?

reactjs - React 路由器渲染未获取 Prop

javascript - 无法使用 useState React 将 Prop 设置为状态

php - 如何将我的 WAMP 放到网上供其他人访问?

javascript - 如何更改 WordPress 发件人姓名?

php服务器端打印

java - 如何从 pom.xml 中提取所有依赖项?

java.lang.NoSuchMethodError : org. apache.fop.apps.FopFactory.newInstance(Ljava/io/File;)Lorg/apache/fop/apps/FopFactory;