You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迁移至DigitalOcean Spaces后图片二进制无法在浏览器显示求助

从S3迁移至DigitalOcean Spaces后图片无法在浏览器显示的排查思路

近期将存储从S3迁移至DigitalOcean Spaces,其他各类文件均能正常工作,但发现图片的二进制内容无法在浏览器中显示。以下是相关PHP代码:

require_login();

$db = new db();
$sql = "SELECT * FROM uploads WHERE id = {$id}";
if (!super()) $sql .= " AND empresa = " . session('empresa');
$file = $db->row($sql);

if (!$file || !session('empresa')) {
    return json_encode(
        [
            'error' => true,
            'message' => 'File not found or you do not have access to it.'
        ]
    );
}

$content =  Storage::read(
    $file->empresa . '/' . $file->modulo . '/' . $file->nome_atual
);

header("Content-Type: {$file->ext}");
header('Content-Disposition: inline; filename="' . $file->nome . '"');
header('Cache-Control: private, max-age=0, must-revalidate');
header('Pragma: public');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');

echo $content;

排查思路:

  • 修正Content-Type字段:代码中直接用$file->ext作为Content-Type是错误的。比如JPG图片的正确MIME类型是image/jpeg,而非jpg。建议:

    • 数据库中存储完整的MIME类型(如image/png、image/jpeg)替代单纯的扩展名
    • 或读取内容后用finfo函数获取正确类型:
      $finfo = new finfo(FILEINFO_MIME_TYPE);
      $mime = $finfo->buffer($content);
      header("Content-Type: {$mime}");
      
  • 确认文件读取完整性:

    • 对比strlen($content)和Spaces上原文件的大小,判断是否读取了完整二进制内容
    • 将$content写入本地文件(如file_put_contents('test.jpg', $content)),检查本地文件能否正常打开,排除读取截断或编码问题
  • 优化响应头配置:

    • 添加Content-Length头帮助浏览器确认文件完整度:header("Content-Length: " . strlen($content));
    • 尝试注释掉Content-Transfer-Encoding: binary头,部分场景下该头会导致图片解析异常
    • 输出前清空缓冲区,避免多余字符干扰:
      ob_clean();
      flush();
      echo $content;
      
  • 检查存储端文件状态:

    • 直接通过DigitalOcean Spaces的文件URL在浏览器打开,确认文件本身未损坏且权限正确(私有文件需生成临时签名URL测试)
  • 修复SQL注入漏洞(额外提示):当前代码直接拼接$id到SQL语句,存在严重安全风险,建议改用参数化查询:

    $sql = "SELECT * FROM uploads WHERE id = ?";
    if (!super()) $sql .= " AND empresa = ?";
    $stmt = $db->prepare($sql);
    if (!super()) {
        $stmt->bind_param("ii", $id, session('empresa'));
    } else {
        $stmt->bind_param("i", $id);
    }
    $stmt->execute();
    $file = $stmt->get_result()->fetch_assoc();
    

内容的提问来源于stack exchange,提问作者Gustavo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 03:39:55