【问题标题】:How to display images of products stored on aws s3 bucket如何显示存储在 aws s3 存储桶上的产品图像
【发布时间】:2022-01-06 05:41:05
【问题描述】:

我正在练习本教程 https://www.youtube.com/watch?v=NZElg91l_ms&t=1234s

它对我来说绝对是一种魅力,但问题是我正在存储产品的图像,我将它们存储在存储桶中,假设我上传了 4 张图片,它们都已上传。 但是当我显示它们时,我在显示列表时遇到拒绝访问错误,并且重复的请求可能会将其检测为垃圾邮件

这就是我试图在我的反应应用程序上获取它们的方式 //其余数据来自mysql数据库(产品名称,价格) //100+ 产品

{ products.map((row)=>{

<div className="product-hero"><img src=`http://localhost:3909/images/${row.imgurl}`</div>
<div className="text-center">{row.productName}</div>
})
}

当它从 db 获取 100 多个产品和从 aws 获取 100 个图像时,它失败了

抱歉这么详细的问题,但简而言之,我如何从我的存储桶中获取所有产品图片

注意我知道我每次调用只能获取一张图片,那么如何在我的场景中一张一张地获取所有图片

//在我的app.js中下载代码

const { uploadFile, getFileStream } = require('./s3')

const app = express()

app.get('/images/:key', (req, res) => {
  console.log(req.params)
  const key = req.params.key
  const readStream = getFileStream(key)

  readStream.pipe(res)
})

//s3 文件

// uploads a file to s3
function uploadFile(file) {
  const fileStream = fs.createReadStream(file.path)

  const uploadParams = {
    Bucket: bucketName,
    Body: fileStream,
    Key: file.filename
  }

  return s3.upload(uploadParams).promise()
}
exports.uploadFile = uploadFile


// downloads a file from s3
function getFileStream(fileKey) {
  const downloadParams = {
    Key: fileKey,
    Bucket: bucketName
  }

  return s3.getObject(downloadParams).createReadStream()
}
exports.getFileStream = getFileStream

【问题讨论】:

    标签: node.js reactjs amazon-web-services amazon-s3


    【解决方案1】:

    您的代码似乎正在向后端发送图像请求,后端从 Amazon S3 检索对象,然后提供图像以响应请求。

    更好的方法是让 HTML 页面中的 URL 直接 指向存储在 Amazon S3 中的图像。这将是高度可扩展的,并会减少您的网络服务器上的负载。

    这将要求图像是公开,以便用户的网络浏览器可以检索图像。最简单的方法是添加一个Bucket Policy,向所有用户授予GetObject 访问权限。

    或者,如果您不希望将存储桶公开,您可以生成 Amazon S3 pre-signed URLs,它们是提供对私有对象的临时访问的限时 URL。您的后端可以使用几行代码计算预签名的 URL,然后用户的 Web 浏览器将能够从 S3 检索私有对象以显示在页面上。

    【讨论】:

    • 我已经向所有人公开了我的存储桶,只是为了让它正常工作,但是当我循环并且请求被垃圾邮件发送时,它会在 heroku 控制台中拒绝访问
    • 我的建议是,不要从 http://localhost:3909/images/... 提供图像,而是从 Amazon S3 直接提供图像,例如 http://bucketname.s3.amazonaws.com/images/...
    • 拒绝访问,但我设置了具有读写权限的 IAM 策略 屏幕截图:drive.google.com/file/d/1ZYQIoK026arDhwZv1A7mkBg3himsXqan/…
    • 请参阅我上面的建议 - 您可以使用 Bucket Policy 而不是 IAM 策略公开存储桶的内容。这样,匿名用户无需在 URL 中提供任何身份验证信息即可访问对象。或者,您可以在创建每个对象时使用ACL='public-read',这将使它们在对象级别公开。哦,还要确保为存储桶策略或 ACL停用 S3 阻止公共访问
    • 对不起,我把它弄混了,让我听从建议,因为我得到了这个drive.google.com/file/d/1-nVij_ESdubvokmZhEzlpd_0oKNm6NlR/… 如果我尝试使用存储桶 url 访问它
    【解决方案2】:

    我在处理博客的图片上传功能时进行了类似的 S3 图片处理,但我没有使用 getFileStream() 上传图片。

    因为在图像文件完全处理之前什么都不应该做,所以我使用fs.readFile(path, callback) 来读取数据。

    我的方式会生成缓冲区数据,但 AWS S3 足够聪明,知道将其截取为图像。 (我只是在文件名中添加了后缀,我不知道如何应用图像标题...)

    这是我的部分代码供参考:

    fs.readFile(imgPath, (err, data) => {
            if (err) { throw err }
            // Once file is read, upload to AWS S3
            const objectParams = {
              Bucket: 'yuyuichiu-personal',
              Key: req.file.filename,
              Body: data
            }
            S3.putObject(objectParams, (err, data) => {
              // store image link and read image with link
            }
    }
    

    【讨论】:

    • 我在上传时没有任何问题,我只想显示我的产品列表及其图片,我也没有使用 getFileStream() 上传图片。我正在使用它从存储桶中获取图像
    • 每个上传的 AWS S3 对象都应该有一个如下所示的路径:
    • https://${bucket}.s3.us-west-1.amazonaws.com/${req.file.filename}
    • 是的,当我想在没有循环的情况下显示单个图像时,它就是这样工作的。但正如我在我的问题中提到的那样它正在工作并且我想显示图像列表然后它不起作用
    • 这将是您的图片链接,您可以将其应用于 img 标签中的 src 属性
    猜你喜欢
    • 1970-01-01
    • 2017-03-13
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多