从 node.js 将图像上传到 s3 存储桶

Posted

技术标签:

【中文标题】从 node.js 将图像上传到 s3 存储桶【英文标题】:Uploading image to s3 bucket from node.js 【发布时间】:2020-12-30 07:55:22 【问题描述】:

node.js 代码如下

在“ap-south-1”区域创建了一个存储桶 您可以在公开上查看的存储桶链接 :- https://iamgroot007.s3.ap-south-1.amazonaws.com/deadpool.png

const AWS = require("aws-sdk");
const fs = require("fs");
const BUCKET = process.env.BUCKET;
const REGION = process.env.REGION;
const ACCESS_KEY = process.env.ACCESS_KEY_ID;
const SECRET_KEY = process.env.SECRET_ACCESS_KEY;
const localImage = "./ap.png";
const imageRemoteName = `catImage_$new Date().getTime().png`;

router.post("/image-upload", (req, res) => 
  AWS.config.update(
    accessKeyId: ACCESS_KEY,
    secretAccessKey: SECRET_KEY,
    region: REGION,
  );

  const s3 = new AWS.S3();

  s3.putObject(
    Bucket: BUCKET,
    Body: fs.readFileSync(localImage),
    Key: imageRemoteName,
  )
    .promise()
    .then((response) => 
      console.log(`done! - `, response);
      console.log(
        `The URL is $s3.getSignedUrl("getObject", 
          Bucket: BUCKET,
          Key: imageRemoteName,
        )`
      );
    )
    .catch((err) => 
      console.log("failed:", err);
    );

出现错误:-

消息: '无法访问的主机:s3.ap-south-1\'. This service may not be available in the ap-south-1,'区域。', 代码:'未知端点', 地区:'ap-south-1,', 主机名:'s3.ap-south-1', 可重试:真, 原始错误: 错误:getaddrinfo ENOTFOUND s3.ap-south-1 s3.ap-south-1:443 在 GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:26) 消息:'getaddrinfo ENOTFOUND s3.ap-south-1 s3.ap-south-1:443', 错误号:'ENOTFOUND', 代码:“网络错误”, 系统调用:'getaddrinfo', 主机名:'s3.ap-south-1', 主机:'s3.ap-south-1', 端口:443, 地区:'ap-south-1,', 可重试:真, 时间:2020-09-11T19:08:30.062Z , 时间:2020-09-11T19:08:30.062Z

【问题讨论】:

错误消息中的主机名 (`s3.ap-south-1\`) 是否确实有尾斜杠,或者是您的某种复制/粘贴错误?您是否通过记录验证了您的 BUCKET 和 REGION 环境变量值实际上是正确的? 是的,我的存储桶和区域名称是正确的,错误已按原样粘贴 与您的连接问题无关,您初始化imageRemoteName 的方式是错误的。您应该将其移动到函数处理程序中。按照您编写的方式,如果 Lambda 函数在调用时是热的(在这种情况下,函数处理程序之外的初始化代码不会重新运行),则多个上传可能会写入同一个 cat 文件。 感谢您的建议。我会按照你说的更新 实际上也许这甚至没有在 Lambda 上运行,但评论仍然是您应该在上传路由处理程序中初始化 imageRemoteName。您可以在同一系统上运行 awscli 吗?也许测试 awscli 在命令行中使用相同的 BUCKET 和 REGION 环境变量将对象上传到同一个 ap-south-1 存储桶。 【参考方案1】:

有两个错误 1> 在 .env 文件夹中,我在 secretKey、accessKey 和 Bucket 名称之后有“,” 2> 我没有使用 multer 中间件来接受传入的 FormData

上传图片的工作代码是:-

const s3 = new AWS.S3(
  accessKeyId: ACCESS_KEY,
  secretAccessKey: SECRET_KEY,
);

const storage = multer.memoryStorage(
  destination: function (req, file, callback) 
    callback(null, "");
  ,
);

const upload = multer( storage ).single("image");

router.post("/image-upload", upload, (req, res) => 
  let fileName = req.file.originalname.split(".");
  const myFileType = fileName[fileName.length - 1];
  const Key = `shopLogo/$uuidv4().$myFileType`;
  console.log(fileName, myFileType, Key, BUCKET);
  const params = 
    Bucket: BUCKET,
    Key,
    Body: req.file.buffer,
  ;

  s3.upload(params, (err, data) => 
    if (err) 
      res.status(500).send(err);
    
    res.status(200).send(data);
  );
);

【讨论】:

以上是关于从 node.js 将图像上传到 s3 存储桶的主要内容,如果未能解决你的问题,请参考以下文章

将图像从 S3 存储桶下载到 Lambda 临时文件夹 (Node.js)

使用带有 Node.js 的 AWS Lambda 函数从 S3 存储桶中提取 zip 文件并上传到另一个存储桶

Node js - 在上传时配置 aws s3 图像

将图像从 opencv 上传到 s3 存储桶

从 url 下载文件并将其上传到 AWS S3 而不保存 - node.js

将图像从库上传到s3存储桶 - 创建文件对象?