0

我正在尝试使用该apollo-upload-client库通过 graphql 将图像上传到 S3,该库仅提供通过 graphql 查询发送图像的能力。因此,图像在 S3 存储桶中进行了叙述,但是当我尝试读取 Location 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,它工作得很好。提前感谢您的任何建议!

4

1 回答 1

0

因此,经过更深入的研究,问题似乎出在serverless框架上,特别是serverless-offline. 它不允许传输二进制数据。因此,我尝试将其转换createReadStreambase64字符串,但这也不起作用。

这是尝试:

 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。

这些是一些具有相同问题的帖子,但没有一个得到解决方案。

https://stackoverflow.com/questions/61050997/file-uploaded-successfully-to-s3-using-serverless-api-but-it-doesnt-opencorrup

使用 NodeJS 从 AWS Lambda 将图像上传到 s3 会导致文件损坏

更新:所以这绝对不是我的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.

于 2021-06-24T13:18:11.963 回答