javascript 使用nodejs从AWS S3存储桶下载图像文件,更新日期:12/12

gcuhipw9  于 2022-12-17  发布在  Java
关注(0)|答案(1)|浏览(84)

我想将图像存储在S3桶中,然后使用AWS的SDK for nodejs通过http请求下载图像。
这是我的布景

// aws.js
const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3');

const config = ({
  region:  'us-east-2',
  credentials: {
    accessKeyId: "ACCESS_KEY",
    secretAccessKey: "SECRET_ACCESS_KEY"
  }
})

const s3Client = new S3Client(config);

const bucketParams = {
  Bucket: 'aws-bucket',
  Key: 'image1.jpg'
}

const getS3 = async () => {
  try {
    const data = await s3Client.send(new GetObjectCommand(bucketParams));
    return await data.Body.transformToString();
  } catch (err) {
    console.log('err:', err);
  }
}

getS3()
  .then((res) => {
    console.log('res:', res)
  })
  .catch((err) => {
    console.log('err:', err);
  });

当我发送请求时,我希望看到一个url,或者一个对象中的url打印到控制台,如下所示:

res: "https://test-bucket-from-nodejs-sdk.s3.us-east-2.amazonaws.com/image1.jpg"

// or

res: ["https://test-bucket-from-nodejs-sdk.s3.us-east-2.amazonaws.com/image1.jpg"]

这是打印到控制台的内容

res: �����%��~       Z�����o�~����!������8~�_�O|&��.��=wG��M�f�'C6Ww3�1��H�t�l(f�{)�G�0���~Ο���?�[�'���;�t��|=��F�Ƌ&��ƭ$�鬓Γyq)����+�@?d���F����amw᎗����W���\����4�:��PI��¤W��_�H��O*        %�F���Dg���%�oŽw�m��u�{=N��(|I=�CCԗP�q
           ۸�J+���
���A҆��$���q�sx��L8K�\*�cߊ���O��6�.��_
s���������w���?���|W�S��.�R49 �S���%�o��4�O<]&7Eq�N���~��_�ટ�����|n�|k������ׅ�/�>�
N<2� + �9H@�x���N�
Y�x3X�{��K��y<]�B�_��<7���I����1Ln��I-�E��K
                                           ��
*[���dN�SE|����^��|5⋋/k>
��mWP�u(`��c5��մ�K�R�q
                      �����w~ֿ
                             >"��⯀�[��_5(�|C��¢��+}F�YU�g����r�)U�B� OQ_���U|u�|S�Ś?�t�M:�U���O.-[Q��P���nKFm�۱,�b��]dT�<-�9��|W�v��徛��L|y�|5մ
                                                                   �8����Zƥk�Em�[��4X���i$�Y���K�

我认为这是因为图像文件在节点服务器环境中不可读,这可能解释了替换字符。
这是否意味着我需要某种中间件(如缓冲区)来使图像文件可读?

  • 更新

我已经解决了一半的问题...我使用了错误的S3 Client方法。我应该使用的是ListObjectsV2Command而不是GetObjectCommand
更新代码:

///aws.js
const { S3Client, ListObjectsV2Command } = require('@aws-sdk/client-s3');

const s3Client = new S3Client(config);

const getS3List = async () => {
  const command = new ListObjectsV2Command({Bucket:'test-bucket-from-nodejs-sdk'});
  const response = await s3Client.send(command);
  return response;
}

getS3List()
  .then((data) => {
    console.log('data:', data);
  })

这将返回一个json对象,其中包含s3存储桶中的对象键列表

// bash window
node aws.js 
data: {
  '$metadata': {
    httpStatusCode: 200,
    requestId: 'FH5WZY9VXGGQ5BWC',
    extendedRequestId: 'pCMCEpPggwNka9Sj/jWZpFo8HmT/j2gd2B93i/COf8v3clgBWfK1Zw5tK3jbChOEuqKd756vRes=',
    cfId: undefined,
    attempts: 1,
    totalRetryDelay: 0
  },
  Contents: [
    {
      Key: 'helloWorld.txt',
      LastModified: 2022-12-12T01:13:23.000Z,
      ETag: '"5eb63bbbe01eeed093cb22bb8f5acdc3"',
      ChecksumAlgorithm: undefined,
      Size: 11,
      StorageClass: 'STANDARD',
      Owner: undefined
    },
    {
      Key: 'image1.jpg',
      LastModified: 2022-12-12T01:09:41.000Z,
      ETag: '"8b82adec06401f845e9564b05d3908dd"',
      ChecksumAlgorithm: undefined,
      Size: 192757,
      StorageClass: 'STANDARD',
      Owner: undefined
    }
  ],
  IsTruncated: false,
  KeyCount: 2,
  MaxKeys: 1000,
  Name: 'test-bucket-from-nodejs-sdk',
  Prefix: ''
}

现在的问题是使用键创建一个工作URL来Map图像标记,我尝试使用对象URL和s3 URI地址作为src属性,但两者都不起作用。

// server.js
app.get('/test', (req, res) => {
  getS3List()
    .then((data) => {
      console.log(data.Contents[1].Key)
      res.send(`<img src='https://test-bucket-from-nodejs-sdk.s3.us-east-2.amazonaws.com/${data.Contents[1].Key}'/>`)
    })
    .catch((err) => {
      throw err;
    })
})

有什么想法吗?
我希望S3服务器返回存储在桶中的图像的url,我可以将其用作html标记的src。当我调用/test端点时,我希望返回带有s3图像url的标记,并在浏览器窗口上呈现
例如:预期行为

// app.js
app.get('/test', (req, res) => {
  getS3List()
    .then((data) => {
      console.log(data.Contents[1].Key)
      res.send(`<img src=${'https://res.cloudinary.com/darp0mj9i/image/upload/v1670551774/fabio/theater/Dario_Fo_s_theatrical_show_G._Polidori_designer_uwv3mf.jpg'}></img>`)
    })
    .catch((err) => {
      throw err;
    })
})

呈现了这个

但这正是我使用s3对象url时所发生的情况

app.get('/test', (req, res) => {
  getS3List()
    .then((data) => {
      console.log(data.Contents[1].Key)
      res.send(`<img src='https://test-bucket-from-nodejs-sdk.s3.us-east-2.amazonaws.com/${data.Contents[1].Key}'></img>`)
    })
    .catch((err) => {
      throw err;
    })
})

这意味着它不是一个有效的网址

4dc9hkyq

4dc9hkyq1#

为了访问存储在AWS S3存储桶中的对象的url,您需要启用公共读取访问权限或创建一个预签名的url,以给予临时访问权限。
无论哪种方式,代码现在的行为都符合预期。
它会在浏览器上返回渲染的图像:

  • 工作溶液:
// aws.js 

const { S3Client, ListObjectsV2Command } = require('@aws-sdk/client-s3');

const config = ({
  region:  'us-east-2',
  credentials: {
    accessKeyId: "ACCESS_KEY",
    secretAccessKey: "SECRET_ACCESS_KEY"
  }
})

const s3Client = new S3Client(config);

const getS3List = async () => {
  const command = new ListObjectsV2Command({Bucket:'test-bucket-from-nodejs-sdk'});
  const response = await s3Client.send(command);
  return response;
}
module.exports = { getS3List }

// server.js

const express = require('express');
const app = express();
app.use(express.json());
const { getS3List} = require('./aws.js');

app.get('/test', (req, res) => {
  getS3List()
    .then((data) => {
      let image = data.Contents[1].Key;
      console.log('image:', image);
      res.send(`<img src='https://test-bucket-from-nodejs-sdk.s3.us-east-2.amazonaws.com/${image}'></img>`)
    })
    .catch((err) => {
      throw err;
    })
})
  • 启用公共访问:

https://aws.amazon.com/premiumsupport/knowledge-center/read-access-objects-s3-bucket/

相关问题