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

TRPC返回图片数据报错求助:无法转换服务器响应

TRPC返回图片数据时出现「TRPCClientError: Unable to transform response from server」的解决方法

问题场景

作为TRPC新手,在开发包含产品图片的应用时,调用TRPC接口返回图片数据时触发错误:TRPCClientError: Unable to transform response from server,核心需求是实现TRPC正常返回并渲染图片数据。


相关代码参考

后端Prisma Product模型

model Product {
  id        Int      @id @default(autoincrement())
  name      String
  image     Bytes?   // 常见存储二进制图片的字段类型
  createdAt DateTime @default(now())
}

后端TRPC Query接口

import { initTRPC } from '@trpc/server';
import { z } from 'zod';
import { prisma } from '../lib/prisma';

const t = initTRPC.create();

export const appRouter = t.router({
  getProductById: t.procedure
    .input(z.number())
    .query(async ({ input }) => {
      return await prisma.product.findUnique({
        where: { id: input },
        select: { id: true, name: true, image: true }
      });
    })
});

export type AppRouter = typeof appRouter;

前端React调用代码

import { useQuery } from '@tanstack/react-query';
import { api } from '../utils/trpc';

export default function ProductCard({ productId }: { productId: number }) {
  const { data: product, error, isLoading } = api.getProductById.useQuery(productId);

  if (isLoading) return <div>加载中...</div>;
  if (error) return <div>错误:{error.message}</div>;

  return (
    <div className="product-card">
      <h3>{product?.name}</h3>
      {product?.image && <img src={product.image} alt={product.name} />}
    </div>
  );
}

核心问题及解决方法

1. 二进制数据序列化失败(最常见原因)

如果Prisma的image字段是Bytes类型,TRPC默认的JSON序列化无法处理Buffer对象,导致转换失败。

解决步骤:

  • 后端将Buffer转为Base64字符串:
    // 修改TRPC query方法
    .query(async ({ input }) => {
      const product = await prisma.product.findUnique({
        where: { id: input },
        select: { id: true, name: true, image: true }
      });
      // 把二进制Buffer转成Base64
      if (product?.image) {
        product.image = product.image.toString('base64');
      }
      return product;
    })
    
  • 前端拼接图片URI渲染:
    {product?.image && (
      <img 
        src={`data:image/png;base64,${product.image}`} 
        alt={product.name} 
      />
    )}
    

2. 前后端序列化器不匹配

如果返回的数据包含复杂类型(如Date、Buffer),默认序列化器无法处理,需要使用superjson统一序列化逻辑。

解决步骤:

  • 安装依赖:npm install superjson
  • 后端配置transformer:
    import { initTRPC } from '@trpc/server';
    import superjson from 'superjson';
    
    const t = initTRPC.create({
      transformer: superjson,
    });
    
  • 前端客户端同步配置:
    // 前端trpc客户端初始化文件
    import { createTRPCReact } from '@trpc/react-query';
    import superjson from 'superjson';
    import type { AppRouter } from '../server/router';
    
    export const api = createTRPCReact<AppRouter>();
    
    export const trpcClient = api.createClient({
      url: '/api/trpc',
      transformer: superjson,
    });
    

3. 图片路径访问问题

如果数据库存储的是图片文件的相对路径,直接返回会导致前端无法正确加载。

解决方法:
后端返回时拼接完整的访问URL:

.query(async ({ input }) => {
  const product = await prisma.product.findUnique({
    where: { id: input },
    select: { id: true, name: true, image: true }
  });
  if (product?.image) {
    // 假设图片存储在public/images目录下,拼接绝对路径
    product.image = `${process.env.NEXT_PUBLIC_APP_URL}/images/${product.image}`;
  }
  return product;
})

快速排查技巧

  1. 直接在后端打印Prisma查询结果,确认image字段的类型和内容。
  2. 开启TRPC调试模式,查看服务器返回的原始响应:
    // 后端添加日志
    import { loggerLink } from '@trpc/server/adapters/standalone';
    
    const t = initTRPC.create({
      links: [loggerLink()],
    });
    
  3. 检查前端Network面板,查看TRPC接口的响应内容是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:35:55