如何从MongoDB存储的Node.js Buffer还原图片并在React中展示?
问题
从OpenAI DALL-E 2 API获取base64编码的图片数据,转为Node.js Buffer后存入MongoDB(Schema.Types.Buffer类型)。使用Apollo GraphQL自定义ImgBinData标量处理Image模型的binData字段,但无法将存储的Buffer还原为前端img元素可用的图片源,不确定是否需要修改自定义标量的serialize方法。
现有代码
React组件代码
import React from "react"; import { useQuery } from "@apollo/client"; import { GET_IMAGE_BY_ID } from "../utils/queries"; const ProfilePicture = () => { const { loading, error, data } = useQuery(GET_IMAGE_BY_ID, { variables: { imageId: "64715e7413b66dd4d30eea3b" }, }); if (loading) return null; if (error) return `Error! ${error}`; const imgBinData = data?.imageByImageId.binData.data; console.log(imgBinData); const imgType = "image/png"; const blob = new Blob([new Uint8Array(imgBinData)], { type: imgType}); const src = URL.createObjectURL(blob); return ( <img src={src} className="" alt="A headshot of the user" /> ); }; export default ProfilePicture;
GraphQL自定义标量代码
const { GraphQLScalarType, Kind } = require("graphql"); const imgBinDataScalar = new GraphQLScalarType({ name: "ImgBinData", description: "Custom scalar for storing image bin data in form of Nodejs Buffer type", serialize: (bufferObj) => bufferObj, parseValue: (value) => Buffer.from(value, "base64"), parseLiteral: (ast) => Buffer.from(ast.value, "base64"), }); module.exports = { imgBinDataScalar, };
解决方案
问题核心在于自定义标量的serialize方法:当前直接返回Buffer对象,GraphQL会将其序列化为包含data整数数组的对象,前端需额外解析。更简洁的方式是在serialize阶段将Buffer转为base64字符串,前端直接拼接成data URI即可使用。
修改自定义标量的serialize方法
调整serialize逻辑,将Buffer转为base64字符串返回给前端:
const { GraphQLScalarType, Kind } = require("graphql"); const imgBinDataScalar = new GraphQLScalarType({ name: "ImgBinData", description: "Custom scalar for storing image bin data in form of Nodejs Buffer type", // 将Buffer转为base64字符串,直接供前端使用 serialize: (bufferObj) => bufferObj.toString("base64"), parseValue: (value) => Buffer.from(value, "base64"), parseLiteral: (ast) => Buffer.from(ast.value, "base64"), }); module.exports = { imgBinDataScalar, };
简化React组件代码
前端直接使用返回的base64字符串拼接成data URI,无需创建Blob和Object URL:
import React from "react"; import { useQuery } from "@apollo/client"; import { GET_IMAGE_BY_ID } from "../utils/queries"; const ProfilePicture = () => { const { loading, error, data } = useQuery(GET_IMAGE_BY_ID, { variables: { imageId: "64715e7413b66dd4d30eea3b" }, }); if (loading) return null; if (error) return `Error! ${error}`; const imgBase64 = data?.imageByImageId.binData; const imgType = "image/png"; // 拼接为data URI直接作为img的src属性值 const src = `data:${imgType};base64,${imgBase64}`; return ( <img src={src} className="" alt="A headshot of the user" /> ); }; export default ProfilePicture;
补充说明
serialize方法的作用是将数据库中的Buffer对象转为GraphQL响应可传输的格式,转base64是图片场景下最高效的选择,减少前端解析步骤。- 若保留原Buffer序列化逻辑(返回整数数组),前端现有代码也可正常运行,但需确保图片类型与实际一致(DALL-E返回的图片可能是
image/png或image/jpeg,建议存储时同时记录图片类型字段)。
内容的提问来源于stack exchange,提问作者jcomp_03
相关产品推荐
相关产品推荐

