【问题标题】:Why I cannot show my image(.svg) that uploaded to S3为什么我无法显示上传到 S3 的图像(.svg)
【发布时间】:2019-10-30 04:40:08
【问题描述】:

我已经将一些 svg 图像上传到 S3 存储桶(我已设置为 public-all)。上传所有 svg 图像后。我得到每个图像的 URL。当我点击这些 URL 时,它只是下载图像我。 还。有谁知道为什么当我在 img 标签中使用这些 Url 时(例如<img src='https://***.s3.***.amazonaws.com/***.svg />`)。它只是显示一个损坏的图像

这是我的 lambda 函数

'use strict'


const aws = require('aws-sdk')
const s3 = new aws.S3()
const { parse } = require('aws-multipart-parser')

const response = (statusCode, data) => ({
  statusCode,
  headers: {
    'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': '*'
  },
  body: JSON.stringify(data)
})


exports.handler = async event => {
  const inputData = parse(event, true)

  if (inputData.file) {
    try {
      const params = {
        Bucket: ***,
        region: ***,
        Key: `${inputData.file.filename}`,
        Body: inputData.file.content,
        ACL: 'public-read'
      }

      const s3Response = await s3.upload(params).promise()
      return response(200, { statusCode: 200, url: s3Response['Location'] })
    } catch (error) {
      console.log('Error: ', error)
      return response(500, {
        error: error.message
      })
    }
  } else {
    return response(400, {
      error: 'Please provide input file.'
    })
  }
}

【问题讨论】:

  • 理想情况下,如果 URL 正确,它不应该被破坏。控制台中是否显示任何错误? @CH L
  • 一定是跨站访问问题,查看浏览器日志
  • 大部分看起来像是不正确的 mime 类型。您能否检查 S3 上 svg 文件的内容类型)。它应该设置为 image/svg+xml 。
  • 我不在电脑前,但当我点击网址时,它只是为我下载图片
  • 参考损坏的图像,这是因为 svg 构造不正确。尝试使用不同的 SVG。参考下载而不是查看,设置内容类型应该可以解决这个问题

标签: reactjs amazon-web-services amazon-s3 aws-lambda


【解决方案1】:

您需要将 S3 上 svg 图像的内容类型设置为“image/svg+xml”。

通过 S3 控制台更改内容类型:

  • 在 S3 控制台上选择对象
  • 点击操作
  • 点击更改元数据

  • 将内容类型更改为 image/svg+xml。该值已在下拉菜单中提供。

当您使用 API 网关上传图片时,您可以在 putObject 请求中设置相应的内容类型。

参考:AWS S3 Put Object API documentation

您可以参考以下AWS文档通过JS上传带有ContentType的图片:

https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property

【讨论】:

  • 我已将我的 lambda 添加到问题中。我应该通过 APIGATEWAY 还是 lambda 添加 Content 类型?...
  • @CHL :在 lambda 中,您可以传递 ContentType 参数。但是,您可能需要根据上传的文件类型每次传递不同的 ContentType。比如image/jpeg、image/bmp、image/png等。可能你可以创建一个键值对类型结构体,并根据上传文件的类型传递内容类型。
  • 因为这个 lambda 仅供用户上传图片(.svg .png 等)。所以我只需要将参数从const params = { Bucket: ***, region: ***, Key: `${inputData.file.filename}`, Body: inputData.file.content, ACL: 'public-read' } 更改为const params = { Bucket: ***, region: ***, Key: `${inputData.file.filename}`, Body: inputData.file.content, ACL: 'public-read', ContentType : image/svg+xml }
  • 有时我发现AWS中的文档我很难理解
  • 你会慢慢习惯的。您还可以查看 boto3 - python SDK 文档。我发现它更详细,记录更好。另外,如果它解决了您的问题,请接受答案。
【解决方案2】:

在从 S3 提供 SVG 时,我遇到了类似的问题。在浏览器上打开 svg 网址时,它工作正常,但在 imgs src 属性中传递 url 时,图像损坏。

在将我的svg 与其他工作的svgs 进行比较后,我发现我的svg 中缺少以下属性。

xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"

添加它们后,它开始正常工作。

一定是这样的——

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
...
...
</svg>

【讨论】:

    【解决方案3】:

    我的前端开发人员抱怨同样的问题。怪 AWS!

    出于某种原因,他们将 SVG 图像标记为 binary/octet-stream,而不是标记为 image/svg+xml

    我的后端是用 Golang 开发的,我使用官方 AWS SDK 来上传文件 (https://github.com/aws/aws-sdk-go)。我解决问题的方法是通过参数传递文件的 MimeType (ContentType)。

    如果您没有向 AWS 传递任何 MimeType,那么它们会尝试自动识别您文件的 MimeType,但在某些情况下它们可能会出错。如果您将 MimeType 传递给 AWS,他们将使用您的 MimeType 而不是尝试识别它,这可能会解决问题。

    在我的 Golang 案例中,我使用这个包能够自动识别 MimeType https://github.com/gabriel-vasile/mimetype

        var mimeTypePtr *string
        mime := mimetype.Detect(file)
        if mime != nil {
            mimeType := mime.String()
            mimeTypePtr = &mimeType
        }
        
        uploader := s3manager.NewUploader(cfg)
        result, err := uploader.Upload(&s3manager.UploadInput{
            Bucket:      os.Getenv("AWS_BUCKET"),
            Key:         filename,
            Body:        file,
            ContentType: mimeTypePtr,
        })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-20
      • 1970-01-01
      • 2013-08-24
      • 2016-02-20
      • 2021-06-24
      • 2021-08-28
      • 2016-10-01
      • 2020-07-07
      相关资源
      最近更新 更多