如何使用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
相关产品推荐
相关产品推荐

