file-upload - 为什么当我使用 apollo-server 上传文件时,文件已上传但文件为 0kb?
问题描述
我试图解决这个问题,但我不明白为什么文件被上传但他的大小是 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
解决方案
发生的情况是解析器在文件上传之前返回,导致服务器在客户端完成上传之前做出响应。您需要在解析器中承诺并等待文件上传流事件。
这是一个例子:
在你的情况下:
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}`,
};
},
},
};
请注意,使用这样的文件名来存储上传的文件可能不是一个好主意,因为将来使用相同文件名的上传将覆盖之前的文件。我不确定如果两个客户端同时上传两个同名文件会发生什么。
推荐阅读
- c++ - 按索引设置 std::variant 的值
- python - 在 Windows 中启动 python 脚本的最佳方式是什么?
- c++ - 如何将矢量对象更改为不同的颜色?
- c# - 创建具有二维数组的表矩阵 C#
- javascript - 是否可以在 d3 中选择特定的 X 比例?
- python - 如何从 for 循环动态创建不同的数据帧以存储数据
- css - 如何使可切换的 mat-sidenav 推送也成为 mat-sidenav-content 中的固定标题
- r - 从 R 中的 twitter 源获取子字符串
- android - 构建后对本机编辑文件做出反应
- sql - SQLite & INNER JOIN 查询