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

如何使用graphql-codegen从apollo-angular向apollo-server上传图片?

解决apollo-angular GraphQL文件上传失败的问题

我来帮你排查这个文件上传的问题,从你提供的代码来看,主要是前端参数传递格式不对,加上Apollo Client需要额外配置支持文件上传,咱们一步步来解决:

1. 修正前端的参数传递格式

你当前把文件包装成了{ file }传给picture参数,但在apollo-angular中,对于GraphQL的Upload类型,直接传递原生的File对象就可以了,不需要额外包装。修改你的上传函数:

uploadClicked($event: any) { 
  const file = $event.target.files[0]; 
  if (!file) return; // 先判断用户是否选择了文件,避免空值报错
  
  this.registerGQL.mutate({ picture: file }).subscribe({
    next: (res) => console.log('上传成功:', res),
    error: (err) => console.error('上传失败:', err), // 这里可以捕获具体错误信息,方便排查
  }); 
}

2. 配置Apollo Client支持文件上传

默认的Apollo HTTP链接不会处理文件上传需要的multipart/form-data请求,所以需要改用支持上传的链接:

首先确保安装了依赖(如果还没装的话):

npm install apollo-upload-client

然后修改你的GraphQL模块配置,用createUploadLink替代普通的createHttpLink:

import { createUploadLink } from 'apollo-upload-client';
import { ApolloModule, APOLLO_OPTIONS } from 'apollo-angular';
import { InMemoryCache } from '@apollo/client/core';

export function createApollo() {
  const uploadLink = createUploadLink({
    uri: '你的GraphQL服务端地址', // 比如 http://localhost:4000/graphql
  });

  return {
    link: uploadLink,
    cache: new InMemoryCache(),
  };
}

@NgModule({
  exports: [ApolloModule],
  providers: [
    {
      provide: APOLLO_OPTIONS,
      useFactory: createApollo,
    },
  ],
})
export class GraphQLModule {}

3. 检查服务端的潜在问题

除了前端的问题,服务端也有几个需要注意的点:

  • 确保图片目录存在:你的代码直接写入__dirname + /../../../images/${filename},如果这个目录不存在,写入会失败。可以在写入前递归创建目录:
    import { mkdirSync, existsSync } from 'fs';
    
    async register( 
      @Arg("picture", () => GraphQLUpload) { createReadStream, filename }: any 
    ): Promise<string> { 
      console.log(__dirname); 
      try { 
        // 先创建图片目录(如果不存在)
        const imageDir = __dirname + '/../../../images';
        if (!existsSync(imageDir)) {
          mkdirSync(imageDir, { recursive: true });
        }
    
        const promise = await new Promise(async (resolve, reject) => 
          createReadStream() 
            .pipe(createWriteStream(`${imageDir}/${filename}`)) 
            .on("finish", () => resolve(true)) 
            .on("error", (err) => reject(err)) // 这里把错误传递出去,方便排查
        );
        return "上传成功"; // 可以返回有意义的信息,而不是空字符串
      } catch (err) { 
        console.log(err); 
        throw new Error(`上传失败: ${err}`); // 抛出错误,让前端能捕获到
      } 
    }
    
  • 确保服务端启用了Upload支持:如果你的Apollo Server版本较新,需要使用graphql-upload的中间件,比如在Express中:
    import { graphqlUploadExpress } from 'graphql-upload';
    import express from 'express';
    
    const app = express();
    // 添加文件上传中间件,配置最大文件大小等参数
    app.use(graphqlUploadExpress({ maxFileSize: 10 * 1024 * 1024, maxFiles: 10 }));
    

做完这些修改后,应该就能正常上传图片了。如果还是有错误,可以在前端的error回调里打印具体的错误信息,这样能更精准地定位问题。

内容的提问来源于stack exchange,提问作者S. Karki

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:33:11