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

如何从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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 08:25:19