【问题标题】:Delete multiple images from aws从 aws 中删除多个图像
【发布时间】:2021-09-30 20:41:20
【问题描述】:

这是我用于从 aws 中删除多个图像的代码

AWS.config.update({
  accessKeyId: process.env.ACCESS_KEY,
  secretAccessKey: process.env.SECRET_ACCESS_KEY
})

const s3 = new AWS.S3({
  params: {
    Bucket: process.env.BUCKET
  }
})

这是我从前端传递来删除图片的数组

const array = [
  'https://s3.amazonaws.com/lgfit/picture/5b55a7a6c316686bbbbc8120.jpg',
  'https://s3.amazonaws.com/lgfit/picture/5b4c3ca0097c915e38d0d21515-09-2018_12_13_48.jpg'
]

我在 deleteObject of aws 中传递图像

var options = {
  Bucket: process.env.BUCKET,
  Delete: {
    Objects: [{
      Key: array
    }],
  }
}
return new Bluebird((resolve) => {
  s3.deleteObject(options, function (err,data){
    console.log(err)
    console.log(data)
  })
})

我收到以下错误

{ MultipleValidationErrors: There were 2 validation errors:
* MissingRequiredParameter: Missing required key 'Key' in params
* UnexpectedParameter: Unexpected key 'Delete' found in params
    at ParamValidator.validate (/home/user/ashish/FitnessApp/Fitness-New-one/fitnessapp-backend/node_modules/aws-sdk/lib/param_validator.js:40:28)
    at Request.VALIDATE_PARAMETERS (/home/user/ashish/FitnessApp/Fitness-New-one/fitnessapp-backend/node_modules/aws-sdk/lib/event_listeners.js:108:42

请帮助我在这里做错了什么!!!

【问题讨论】:

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


    【解决方案1】:

    您的代码中有两个错误。

    1. 您使用了错误的 SDK 方法。
    2. 您以错误的格式传递参数。

    deleteObjects是删除多个对象的方法 和 Delete.Objects 期望 key:string 但你给 key:array 所以你需要从你的数组中生成对象。我假设lgfit 是您的存储桶。

    const params = {
        Bucket: process.env.BUCKET,
        Delete: {
            Objects: [{
                    Key: "picture/5b55a7a6c316686bbbbc8120.jpg"
                },
                {
                    Key: "picture/5b4c3ca0097c915e38d0d21515-09-2018_12_13_48.jpg"
                }
            ],
            Quiet: false
        }
    };
    return new Bluebird((resolve) => {
        s3.deleteObjects(params, function (err, data) {
            if (err) console.log(err, err.stack); // an error occurred
            else console.log(data); // successful response
            /*
            data = {
            Deleted: [
                {
            DeleteMarker: true, 
            DeleteMarkerVersionId: "A._w1z6EFiCF5uhtQMDal9JDkID9tQ7F", 
            Key: "objectkey1"
            }, 
                {
            DeleteMarker: true, 
            DeleteMarkerVersionId: "iOd_ORxhkKe_e8G8_oSGxt2PjsCZKlkt", 
            Key: "objectkey2"
            }
            ]
            }
            */
        });
    });
    

    【讨论】:

    • 谢谢!!!它工作完美!所以我需要从图像中删除前缀?
    • 是的,因为您已经提供了存储桶名称,因此您需要提供该存储桶根目录的相对路径。
    • 这里的Quiet: false 是什么?
    • 多对象删除操作支持两种响应模式;冗长而安静。默认情况下,该操作使用详细模式,其中响应包括删除请求中每个键的结果。在安静模式下,响应仅包括删除操作遇到错误的键。对于成功删除,该操作不会在响应正文中返回有关删除的任何信息。
    【解决方案2】:

    由于您尝试使用单个 HTTP 请求删除多个对象,因此您应该使用 s3.deleteObjects() 而不是 s3.deleteObject()。您可以尝试以下操作:

    var options = {
      Bucket: process.env.BUCKET,
      Delete: {
        Objects: [{
          Key: array[0]
        },
        {
          Key: array[1]
        }],
      }
    }
    return new Bluebird((resolve) => {
      s3.deleteObjects(options, function (err,data){
        console.log(err)
        console.log(data)
      })
    })
    

    【讨论】:

    • 现在得到这个InvalidParameterType: Expected params.Delete.Objects[0].Key to be a string
    • 我认为现在的问题是您将键作为数组提供,其中键应该是字符串,而对象应该是具有多个键作为位置图像对象的数组。看看这里:docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/…
    • 有趣的是,s3.deleteObject() 和 s3.deleteObjects() 之间的细微差别让我在梦中思考。我很傻,谢谢@Ashish
    【解决方案3】:

    将数组更改为对象

    const imgList = [
      {Key: 'picture/5b55a7a6c316686bbbbc8120.jpg'},
      {Key: 'picture/5b4c3ca0097c915e38d0d21515-09-2018_12_13_48.jpg'}
    ]
    

    在参数中将数组设置为对象值

    const params = {
        Bucket: process.env.BUCKET,
        Delete: {
            Objects: imgList,
            Quiet: false
        }
    };
    

    现在删除对象

    return new Bluebird((resolve) => {
        s3.deleteObjects(params, function (err, data) {
            if (err) console.log(err, err.stack); // an error occurred
            else console.log(data); // successful response
        });
    });
    

    Learn more from official docs

    【讨论】:

      【解决方案4】:

      我更喜欢这种方法,它允许我同时删除单个和多个图像

      假设我有产品和类别多张图片,假设产品由 2 张图片组成。

      在这里,我将为我的删除逻辑编写全局函数,以便我可以在任何需要的地方使用此逻辑。

      在我的控制器中 (AWS-s3.js)

      // global function for deleting image from aws s3
      const deleteImageFromAws = async (image) => {
      const buckets = {
      Bucket: "ultimodeal-image-test",
      Key: image,
          };
      
       s3.deleteObject(buckets, (err, data) => {
        if (err) {
        console.log("Error while deleting image from aws s3", err);
        }
        });
       };
      

      我的产品模型(product.Models.js)

      const productSchema = new Schema({
       name: {
        type: String,
        required: true,
        trim: true,
      },
      
      price: {
        type: Number,
        required: true,
      },
      quantity: {
        type: Number,
        required: true,
      },
       productPictures: [
      // [0]:keys:todo2.png,img:https://mybucket.s3.ap-south-1.amazonaws.co/todo2.jpg
      //[1] keys:poc2.jpg, img: https://mybucket.s3.ap-south-1.amazonaws.com/poc2.jpg
        {
          keys: {  // for eg: keys:todo2.jpg which is same key from my bucket
            type: String, 
          },
          img: {
            type: String, // for eg: img: https://mybucket.s3.ap-south-   1.amazonaws.com/todo2.jpg
          },
        },
      ],
      const Product = mongoose.model("product", productSchema);
      module.exports = Product;
      

      现在我有另一个控制器(Products.Controllers.js),在这里我将简单地调用我的全局删除函数。所以,我的图像是数组形式(即多个图像)并且通过映射提取我可以删除多个图像aws-s3.你可以看到输出deleteImage 作为回应,这将显示多个图像删除

      const { deleteImageFromAws } = require("../AWS-S3.Image");// 
      
      exports.deleteProduct = async (req, res) => {
       try {
        const { productId } = req.params;
        const checkProductImage = await Product.findOne({ _id: productId });
      
      if (productId) {
        const removedProduct = await Product.findOneAndDelete({ _id: productId });
      
        if (!removedProduct) {
          return res.status(400).json({
            status: false,
            message: `The product of id: ${productId} is not available in database`,
          });
        } else {
          const deleteImage = checkProductImage.productPictures.map((image) => {
            deleteImageFromAws(image.keys); // calling deleting function which will delete multiple images
            return image.keys;
          });
          return res.status(200).json({
            status: true,
            message: `The Product with this productId ${productId} is deleted Succesfully...`,
            deleteImage,
          });
        }
      } else {
        return res.status(409).json({
          status: false,
          error: "Opps..Cannot deleted",
        });
      }
        } catch (error) {
         return res.status(500).json({
        status: false,
        error: error.message,
        });
        }
       };
      

      图:从我的 aws 存储桶中删除了两张图片。如果您的产品型号只有 1 张图片,那么它将仅删除该产品 ID 的 1 张图片

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-12
        • 2018-09-23
        相关资源
        最近更新 更多