我正在尝试使用 apollo-upload-client
库通过 graphql 将图像上传到 S3,该库仅提供通过 graphql 查询发送图像的能力。
所以图像在 S3 存储桶中讲述自己,但是当我尝试读取位置 url 时,它似乎不起作用。当我阅读带有 <img src="img_url" />
的网址时,它只显示:
当我尝试手动输入链接时,它只会自动下载一个带有很多奇怪符号的奇怪文本文件。
这就是 upload
的样子:
export async function uploadImageResolver(
_parent,
{ file }: MutationUploadImageArgs,
context: Context,
): Promise<string> {
// identify(context);
const { createReadStream, filename, mimetype } = await file;
const response = await s3
.upload({
ACL: 'public-read',
Bucket: environment.bucketName,
Body: createReadStream(),
Key: uuid(),
ContentType: mimetype,
})
.promise();
return response.Location;
}
File 对象的示例如下所示:
{
filename: 'Screenshot 2021-06-15 at 13.18.10.png',
mimetype: 'image/png',
encoding: '7bit',
createReadStream: [Function: createReadStream]
}
我做错了什么?它返回一个实际的 S3 链接,但链接本身不显示任何图像。我尝试手动将相同的图像上传到 S3,它工作得很好。提前感谢您的任何建议!
答案 0 :(得分:0)
所以经过更深入的研究,问题似乎出在 serverless
框架上,特别是 serverless-offline
。它不允许传输二进制数据。
所以我尝试将 createReadStream
转换为 base64
字符串,但这也不起作用。
这是尝试:
export async function uploadImageResolver(
_parent,
{ file }: MutationUploadImageArgs,
context: Context,
): Promise<string> {
const { createReadStream, filename, mimetype } = await file;
const response = await s3
.upload({
ACL: 'public-read',
Bucket: environment.bucketName,
Body: (await stream2buffer(createReadStream())).toString('base64'),
Key: `${uuid()}${extname(filename)}`,
ContentEncoding: 'base64',
ContentType: mimetype // image/jpg, image/png, ...
})
.promise();
return response.Location;
}
async function stream2buffer(stream: Stream): Promise<Buffer> {
return new Promise<Buffer>((resolve, reject) => {
let _buf = Array<any>();
stream.on('data', (chunk) => _buf.push(chunk));
stream.on('end', () => resolve(Buffer.concat(_buf)));
stream.on('error', (err) => reject(`error converting stream - ${err}`));
});
}
我也尝试安装 serverless-apigw-binary
插件,但也没有用。
plugins:
- serverless-webpack
- serverless-offline
- serverless-apigw-binary
它正在将相同的损坏图像上传到 s3。
这些是一些有同样问题的帖子,但没有一个得到解决。
Uploading image to s3 from AWS Lambda with NodeJS results in corrupted file
UPDATE:所以这绝对不是我的 s3.upload
函数或 s3
本身的问题。问题似乎是将图像发送到服务器。我很确定这与 serverless
有关。
我创建了一个小函数,它只接收图像并将其加载到本地文件夹中。而且我的图像已损坏:
export async function uploadImageResolver(
_parent,
{ file }: MutationUploadImageArgs,
context: Context,
): Promise<string> {
// identify(context);
const { createReadStream, filename } = await file;
createReadStream().pipe(
createWriteStream(__dirname + `/../../../images/${filename}`),
);
return ''
}
更新 2:我发现它在部署时有效。所以它必须是带有 serverless-offline
的东西。