如何从MongoDB文档中取回图片二进制数据并在客户端正常展示?
如何从MongoDB文档中取回图片二进制数据并在客户端正常展示?
我来帮你梳理下问题的核心,以及一步步解决的方案:
问题根源:你存储的不是图片原始二进制,而是Blob对象的序列化数据
你用bson.serialize(picture)把Blob对象序列化后存入MongoDB,这其实存的是Blob对象的元数据(比如文件名、修改时间),而非图片本身的像素二进制数据。所以你取出来的Binary内容根本不是图片内容,自然没法显示。
步骤1:修正存储逻辑,直接存图片原始二进制
首先要改掉存储方式,把Blob转成纯二进制数据再存入MongoDB,不用序列化Blob对象:
假设服务器端接收的picture是Blob/File对象,先转成Buffer再存储:
// 服务器端处理上传的图片 const pictureBuffer = Buffer.from(await picture.arrayBuffer()); await db.collection("users").updateOne( { email: user.email }, { $set: { picture: pictureBuffer } } // 直接存Buffer,MongoDB会自动转成Binary类型 );
如果是前端上传,也可以先把File转成ArrayBuffer再传给服务器,避免额外处理,但核心是:存的必须是图片的原始二进制,不是Blob对象本身。
步骤2:在SvelteKit的Load函数中安全传递二进制数据
MongoDB返回的picture是Binary类型,没法直接序列化返回给客户端,我们可以把它转成Base64字符串(Base64是可序列化的文本格式):
export const load: PageServerLoad = async ({ cookies }) => { const { user } = await getUser(cookies); return { user: { // 将Binary的buffer转成Base64字符串 picture: user.picture ? user.picture.buffer.toString('base64') : null, email: user.email } }; };
步骤3:客户端用Data URL展示图片
拿到Base64字符串后,我们可以直接生成Data URL赋值给img的src:
<script> export let user; let pictureURL = null; // 注意要匹配图片的真实类型(比如image/png、image/jpeg) if (user.picture) { pictureURL = `data:image/png;base64,${user.picture}`; } </script> {#if pictureURL} <img src={pictureURL} alt="Profile picture" /> {:else} <p>暂无头像</p> {/if}
如果你已经存了错误的数据?
如果数据库里已经有之前序列化的Blob数据,你需要先更新这些记录:要么重新上传图片,要么从序列化的Blob数据中提取出原始图片内容(但这个比较麻烦,不如重新上传简单)。
备注:内容来源于stack exchange,提问作者ThomasG2201
相关产品推荐
相关产品推荐

