如何用MySQL的BLOB图片实现Facebook分享预览图(不落地存储)
问题解决方法
你当前的做法行不通,因为Facebook的Open Graph爬虫不支持data URI格式的og:image值,它会把这个data URI当成纯文本解析,所以显示的是一堆ASCII代码。
要实现不存本地就能让Facebook抓取到预览图,正确的做法是单独写一个PHP脚本,专门用来输出数据库里的BLOB图片数据流,然后在og:image里引用这个脚本的URL。
具体步骤
1. 创建图片输出脚本(比如serve-image.php)
这个脚本负责根据传入的ID从数据库读取BLOB图片,然后输出正确的图片响应:
<?php require_once($_SERVER['DOCUMENT_ROOT']."/includes/config.php"); // 安全处理ID,防止SQL注入 $id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT); if (!$id) { header("HTTP/1.1 400 Bad Request"); exit; } try { // 用预处理语句查询,避免注入 $stmt = $db->prepare("SELECT tabletop_photo, photo_mime_type FROM birdtabletop WHERE id = ? AND approvalMsg = 'Approved' LIMIT 1"); $stmt->execute([$id]); $row = $stmt->fetch(PDO::FETCH_ASSOC); if (!$row || empty($row['tabletop_photo'])) { // 没有图片时返回默认图 header("Location: /images/tabletop.jpg"); exit; } // 输出图片的MIME类型头(如果数据库存了类型就用存的,没存就默认jpeg) $mime = $row['photo_mime_type'] ?? 'image/jpeg'; header("Content-Type: $mime"); header("Content-Length: " . strlen($row['tabletop_photo'])); // 输出图片内容 echo $row['tabletop_photo']; exit; } catch(PDOException $e) { header("HTTP/1.1 500 Internal Server Error"); exit; } ?>
注意:如果你的数据库没存图片的MIME类型,就固定用
image/jpeg(如果所有图片都是JPG格式);如果有PNG等其他格式,需要额外判断处理。
2. 修改原页面的og:image部分
把原来输出data URI的代码改成引用上面的脚本URL:
<?php if($tPicture != NULL){ echo '<meta property="og:image" content="https://www.finchkeeper.com/serve-image.php?id='.htmlspecialchars($keys).'"/>'; }else{ echo '<meta property="og:image" content="https://www.finchkeeper.com/images/tabletop.jpg">'; } ?>
3. 修复原代码的SQL注入风险
原查询语句存在注入隐患,建议改成预处理语句:
// 替换原来的$query和循环逻辑 $stmt = $db->prepare("SELECT * FROM birdtabletop WHERE id = ? AND approvalMsg = 'Approved' LIMIT 1"); $stmt->execute([$keys]); $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row) { $tTitle = $row['tabletop_name']; $tPicture = $row['tabletop_photo']; } else { header('Location: login.php'); exit; }
验证方法
完成后可以用Facebook官方的调试工具刷新页面的分享缓存,确认预览图能正常显示。
内容的提问来源于stack exchange,提问作者Dion
相关产品推荐
相关产品推荐

