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

Next.js Apollo Client向NestJS GraphQL传文件数组后端接收为空的问题

解决Next.js Apollo Client向NestJS GraphQL传File数组后端接收空对象的问题

核心问题原因

GraphQL默认用JSON格式传输数据,无法直接传递File对象。必须通过multipart/form-data协议处理文件上传,你的前后端都缺少对应配置和正确的类型处理逻辑。


后端NestJS修正步骤

1. 安装依赖并配置上传中间件

先安装graphql-upload依赖:

npm install graphql-upload

在AppModule的GraphQL配置中添加文件上传处理中间件:

import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { graphqlUploadExpress } from 'graphql-upload';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: true,
      context: ({ req }) => ({ req }),
      // 注册上传中间件,可根据需求调整文件大小和数量限制
      onModuleInit: async (app) => {
        app.use(graphqlUploadExpress({ maxFileSize: 10 * 1024 * 1024, maxFiles: 10 }));
      },
    }),
  ],
})
export class AppModule {}

2. 修正CreateTaskDto类型定义

确保attachments字段使用GraphQLUpload数组类型:

import { InputType, Field } from '@nestjs/graphql';
import { GraphQLUpload, Upload } from 'graphql-upload';

@InputType()
export class CreateTaskDto {
  @Field(() => String)
  name: string;
  @Field()
  priority: string;
  @Field(() => [String], { nullable: true })
  label?: string[];
  @Field({ nullable: true })
  owner?: string;
  @Field({ nullable: true })
  assignee?: string;
  @Field({ nullable: true })
  dueDate?: string;
  // 正确声明为Upload数组类型
  @Field(() => [GraphQLUpload], { nullable: true })
  attachments?: Upload[];
  @Field({ nullable: true })
  description?: string;
}

3. 正确解析Upload对象

Upload是Promise类型,必须通过await解析才能拿到文件实际信息:

async create(createTaskDto: CreateTaskDto): Promise<TaskResponseToUser> {
  // 解析所有上传的文件
  const resolvedAttachments = createTaskDto.attachments 
    ? await Promise.all(
        createTaskDto.attachments.map(async (upload) => {
          const { createReadStream, filename, mimetype, encoding } = await upload;
          // 这里可添加文件保存逻辑(写入本地/云存储等)
          return { filename, mimetype, encoding };
        })
      )
    : [];
  
  console.log(resolvedAttachments); // 现在能看到正常的文件信息
  return {
    message: 'Task created.',
    status: true,
    data: {
      ...createTaskDto,
      attachments: resolvedAttachments,
    },
  };
}

前端Next.js Apollo Client修正步骤

1. 安装上传支持依赖

npm install apollo-upload-client

用createUploadLink替换默认的createHttpLink,它会自动将File对象转换为multipart/form-data请求:

import { ApolloClient, InMemoryCache } from '@apollo/client';
import { createUploadLink } from 'apollo-upload-client';

const client = new ApolloClient({
  link: createUploadLink({
    uri: '/api/graphql', // 你的GraphQL接口地址
  }),
  cache: new InMemoryCache(),
});

3. 保持现有调用逻辑

你的saveTask函数无需修改,filesSelected作为File数组直接传递即可:

function saveTask() {
  const createTaskDto = {
    name: title,
    priority,
    label: labels,
    owner,
    assignee,
    dueDate,
    attachments: filesSelected,
    description
  };
  if (title) {
    createTask({ variables: { createTaskDto } })
      .then(res => console.log(res))
      .catch(err => console.log(err));
  }
}

关键注意事项

  • 不要用自定义AnyType处理文件上传,GraphQLUpload是官方标准类型
  • 后端必须配置graphqlUploadExpress中间件,否则无法解析multipart请求
  • 前端必须使用createUploadLink,否则Apollo Client会把File序列化为JSON,导致后端收到空对象
  • Upload是Promise类型,必须await解析才能获取实际文件数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:07:21