为啥当我使用 apollo-server 上传文件时,文件已上传但文件为 0kb?

Posted

技术标签:

【中文标题】为啥当我使用 apollo-server 上传文件时,文件已上传但文件为 0kb?【英文标题】:Why when I upload file with apollo-server the file is uploaded but the file is 0kb?为什么当我使用 apollo-server 上传文件时,文件已上传但文件为 0kb? 【发布时间】:2021-05-01 03:13:02 【问题描述】:

我试图解决这个问题,但我不明白为什么文件被上传但他的大小是 0Kb。 我在教程中看到了这段代码,但他在那个教程上工作,但对我不起作用

const  ApolloServer, gql  = require('apollo-server');
const path = require('path');
const fs = require('fs');

const typeDefs = gql`
  type File 
    url: String!
  

  type Query 
    hello: String!
  

  type Mutation 
    fileUpload(file: Upload!): File!
  
`;

const resolvers = 
  Query: 
    hello: () => 'Hello world!',
  ,
  Mutation: 
    fileUpload: async (_,  file ) => 
      const  createReadStream, filename, mimetype, encoding  = await file;
      const stream = createReadStream();
      const pathName = path.join(__dirname, `/public/images/$filename`);
      await stream.pipe(fs.createWriteStream(pathName));

      return 
        url: `http://localhost:4000/images/$filename`,
      ;
    ,
  ,
;

const server = new ApolloServer(
  typeDefs,
  resolvers,
);

server.listen().then(( url ) => 
  console.log(`???? Server ready at $url`);
);

那么当我上传文件时,它是上传的,但是文件是0kb


like this

【问题讨论】:

【参考方案1】:

发生的情况是解析器在文件上传之前返回,导致服务器在客户端完成上传之前做出响应。您需要在解析器中承诺并等待文件上传流事件。

这是一个例子:

https://github.com/jaydenseric/apollo-upload-examples/blob/c456f86b58ead10ea45137628f0a98951f63e239/api/server.js#L40-L41

在你的情况下:

const resolvers = 
  Query: 
    hello: () => "Hello world!",
  ,
  Mutation: 
    fileUpload: async (_,  file ) => 
      const  createReadStream, filename  = await file;
      const stream = createReadStream();
      const path = path.join(__dirname, `/public/images/$filename`);

      // Store the file in the filesystem.
      await new Promise((resolve, reject) => 
        // Create a stream to which the upload will be written.
        const writeStream = createWriteStream(path);

        // When the upload is fully written, resolve the promise.
        writeStream.on("finish", resolve);

        // If there's an error writing the file, remove the partially written
        // file and reject the promise.
        writeStream.on("error", (error) => 
          unlink(path, () => 
            reject(error);
          );
        );

        // In Node.js <= v13, errors are not automatically propagated between
        // piped streams. If there is an error receiving the upload, destroy the
        // write stream with the corresponding error.
        stream.on("error", (error) => writeStream.destroy(error));

        // Pipe the upload into the write stream.
        stream.pipe(writeStream);
      );

      return 
        url: `http://localhost:4000/images/$filename`,
      ;
    ,
  ,
;

请注意,使用这样的文件名来存储上传的文件可能不是一个好主意,因为以后使用相同文件名的上传会覆盖之前的文件。我不确定如果两个客户端同时上传两个同名文件会发生什么。

【讨论】:

以上是关于为啥当我使用 apollo-server 上传文件时,文件已上传但文件为 0kb?的主要内容,如果未能解决你的问题,请参考以下文章

graphql apollo-server 中的文件上传错误

为啥我的php脚本上传应该是图像的空白文件

为啥在php中使用cropper js上传图像时需要不工作

Apollo-Server,如何与 SailsJS 一起使用?

使用纱线工作区时,tsc 在 apollo-server 中找不到 express 的声明文件

twine上传文件到pypi时为啥会弹出如下错误