来自 S3 的 URL 图像不显示图像

Posted

技术标签:

【中文标题】来自 S3 的 URL 图像不显示图像【英文标题】:Url Image from S3 not displaying the image 【发布时间】:2021-09-07 11:36:10 【问题描述】:

我正在尝试使用 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,它工作得很好。提前感谢您的任何建议!

【问题讨论】:

上传问题已经解决...使用搜索? 在发布这个问题之前,我已经搜索了帖子、教程和文档。有一点关于这个graphql-upload-client 的信息。此外,所有教程都在执行相同的步骤。我的问题是我找不到问题,我真的不知道为什么不起作用。 为什么是客户端问题?看起来像一个常见的服务器/API/解析器/节点问题...响应在处理之前返回/关闭...await s3.upload... ? 我在s3.upload.. 之前调用await 我只是没有将它粘贴到示例中抱歉。我将编辑示例代码。 没什么大的变化......有很多corrupt s3 upload问题要挖掘......s3 forward upload(以及相关的'multipart','chunks'),pipe stream,没有缓冲(节省中间存储空间)等..只需搜索更好的示例/答案 【参考方案1】:

所以经过更深入的研究,问题似乎出在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。

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

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

Uploading image to s3 from AWS Lambda with NodeJS results in corrupted file

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

【讨论】:

ContentEncoding: 'base64'ContentType: 'image/png'更新上传选项 那也行不通。上传相同的损坏图像。

以上是关于来自 S3 的 URL 图像不显示图像的主要内容,如果未能解决你的问题,请参考以下文章

如何显示来自 S3/Paperclip/Heroku 的图像?

如何使用 PHP 显示来自 Amazon S3 的图像?

Amazon S3 图像未显示在 Linkedin 或 Facebook 状态更新中

UITableView 不显示来自 URL 的图像 [重复]

无法在 asp.net mvc 中显示来自 s3 存储桶的上传图像

如何在 asp.net mvc 中显示来自 Amazon S3 的图像文件?