如何使用multer-storage-cloudinary包从Cloudinary删除图像?

如何解决如何使用multer-storage-cloudinary包从Cloudinary删除图像?

我可以使用multer-storage-cloudinary包成功上传图像,但是我还没有拼凑出如何通过更新或删除路线销毁cloudinary中图像的实现。我发现的所有资源仅参考上传图像。这是我必须上传的图片

Option Explicit

Sub sortByCriteria()

    ' Constants
    Dim SheetNames As Variant: SheetNames = Array("Sheet1","Sheet1")
    Dim FirstRows As Variant: FirstRows = Array(2,2)
    Dim Cols As Variant: Cols = Array("A","B")
    Dim wb As Workbook: Set wb = ThisWorkbook ' The workbook with this code.

    ' Write Modifier and Parent ranges to Modifier (Data(1)) and Parent
    ' (Data(0)) Arrays.
    Dim ws As Worksheet,rng As Range,j As Long
    Dim Data As Variant: ReDim Data(1)
    For j = 1 To 0 Step -1
        ' Define current Column Range.
        Set ws = wb.Worksheets(SheetNames(j))
        Set rng = ws.Columns(Cols(j)).Find("*",xlValues,xlPrevious)
        If rng Is Nothing Then Exit Sub
        If rng.Row < FirstRows(j) Then Exit Sub
        Set rng = ws.Range(ws.Cells(FirstRows(j),Cols(j)),rng)
        ' Write current Column Range to current Column Array.
        Dim OneCell As Variant: ReDim OneCell(1 To 1,1 To 1)
        If rng.Rows.Count > 1 Then
            Data(j) = rng.Value
        Else
            Data(j) = OneCell: Data(j) = rng.Value
        End If
    Next
    
    ' Write values from Data Array (Data(0)) to Result Array (Result).
    Dim Result As Variant: ReDim Result(1 To UBound(Data(0)),1 To 1)
    Dim i As Long,k As Long,m As Long
    For i = 1 To UBound(Data(1))
        For k = 1 To UBound(Data(0))
            If Not IsEmpty(Data(0)(k,1)) Then GoSub writeMatches
        Next k
    Next i
    For k = 1 To UBound(Data(0))
        If Not IsEmpty(Data(0)(k,1)) Then GoSub writeRemainder
    Next k
    If m = 0 Then Exit Sub
    
    ' Write values from Result Array (Result) to Data Range (rng).
    rng.Resize(m).Value = Result
    
    ' Inform user.
    MsgBox "Done.",vbInformation,"Success"
    
    Exit Sub

writeMatches:
    If InStr(1,Data(0)(k,1),Data(1)(i,vbTextCompare) > 0 Then
        m = m + 1
        Result(m,1) = Data(0)(k,1)
        Data(0)(k,1) = Empty ' Already checked and written.
    End If
    Return

writeRemainder:
    m = m + 1
    Result(m,1)
    Data(0)(k,1) = Empty ' Already checked and written.
    Return

End Sub

这是处理表单提交的前端代码

const cloudinary = require('cloudinary').v2;
const { CloudinaryStorage } = require('multer-storage-cloudinary');
const multer = require('multer');

cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,api_key: process.env.API_KEY,api_secret: process.env.API_SECRET
});

const storage = new CloudinaryStorage({
  cloudinary: cloudinary,params: {
    folder: "works",allowedFormats: ["jpg","png"]
  }
});
const imgUpload = multer({ storage: storage });

router.post('/',withAuth,imgUpload.single('work-img'),(req,res) => {
  console.log(req.file);

  Post.create({
        title       : req.body.title,dimension   : req.body.dimensions,description : req.body.description,media       : req.body.media,img_url     : req.file.path,user_id     : req.session.user_id
    })
        .then((dbPostData) => res.json(dbPostData))
        .catch((err) => {
            console.log(err);
            res.status(500).json(err);
        });
});

最后,我的更新路线可用于上传新图像并将其新路径保存到数据库,但是我也想从Cloudinary中删除旧图像,因此这里没有未使用的构件。

async function newFormHandler(event) {
    event.preventDefault();

    const form = document.querySelector('#new-post-form');

    const formData = new FormData(form);

    const response = await fetch(`/api/posts`,{
        method : 'POST',body   : formData
    });

    if (response.ok) {
        document.location.replace('/dashboard');
    } else {
        alert(response.statusText);
    }
}

document.querySelector('#new-post-form').addEventListener('submit',newFormHandler);

如果我在发布路线中查看console.log(req.file),它会给我类似的东西

router.put('/:id',res) => {
    Post.update(
        {
            title       : req.body.title,img_url     : req.file.path
        },{
            where : {
                id : req.params.id
            }
        }
    )
        .then((dbPostData) => {
            if (!dbPostData) {
                res.status(404).json({ message: 'No post found with this id' });
                return;
            }
            res.json(dbPostData);
        })
        .catch((err) => {
      console.log(err);
            res.status(500).json(err);
        });
});
根据Cloudinary API文档,响应看起来与“ public_id”之类的键有很大不同。
{
  fieldname: 'work-img',originalname: '20171005_134508.jpg',encoding: '7bit',mimetype: 'image/jpeg',path: 'https://res.cloudinary.com/xxxxxxxxx/image/upload/xxxxxxxx/works/ujrrf13kyil8l5rjccwf.jpg',size: 3647252,filename: 'works/ujrrf13kyil8l5rjccwf'
}

然后我可以像这样用destroy方法使用'public_id',但是我无权配置public_id:cloudinary.v2.uploader.destroy(public_id,options,callback);

我不清楚如何实现此目标,甚至不清楚是否可以使用multer-storage-cloudinary软件包

解决方法

要删除,需要public_id。如果在使用multer-storage-cloudinary时未在响应中得到public_id,则可以在上传时将其作为参数传递,这将是Cloudinary上图像的名称。要删除图像,您只需使用该public_id。或者,您可以使用cloudinary.uploader.upload函数,该函数将返回带有public_id和其他详细信息的JSON,如示例响应中所述。

,

因此,对于可能对我最终的使用方式感兴趣的任何人,如下

router.put('/:id',withAuth,imgUpload.single('work-img'),(req,res) => {
    // if there was a picture updated -- NOTE THIS TECHNIQUE IS NOT DRY,IS THERE A WAY TO REFACTOR?
    if (req.file) {
        // find old public_id for image so we can delete it from cloudinary before updating the db with new path
        Post.findOne(
            {
                where : {
                    id : req.params.id
                }
            },{
                attributes : [ 'title','public_id' ]
            }
        )
            .then((oldPostData) => {
                const oldPublicId = oldPostData.get({ plain: true });

                // remove old image from cloudinary db
                cloudinary.uploader.destroy(oldPublicId.public_id,(err) => {
                    console.log(err);
                    console.log(oldPublicId,' deleted');
                });

                // not in cloudinary callback since deletion from cloudinary is not critical to UX
                Post.update(
                    {
                        title       : req.body.title,artist_name : req.body.artist,dimension   : req.body.dimensions,description : req.body.description,media       : req.body.media,img_url     : req.file.path,public_id   : req.file.filename
                    },{
                        where : {
                            id : req.params.id
                        }
                    }
                ).then((newPostData) => {
                    if (!newPostData) {
                        res.status(404).json({ message: 'No post found with this id' });
                        return;
                    }

                    req.flash('success','Your work has been updated!');
                    res.json(newPostData);
                });
            })
            .catch((err) => {
                console.log(err);
                res.status(500).json(err);
            });
    // in the else i just added the post to the db without the image file.
    } else {...}

如上所述,public_id是您用来访问cloudinary中的映像的对象。因此,multer-storage-cloudinary中间件负责从表单中获取图像并将其直接上传到cloudinary,然后将来自cloudinary的响应打包到req.file中,而multer通常将其添加到req对象中。 (显然,需要使用新的public_id字段来更新架构)。在PUT回调中,查询数据库中的帖子并获取旧的public_id。解析它,并将其传递给cloudinay.uploader.destroy()方法。如果您的路线与imgUpload配置位于单独的文件中,则需要使用cloudinary。那么您可以从cloudinary回调内部更新数据库,也可以不从内部更新,因为它们彼此不依赖,并且cloudinary操作对于用户体验不是至关重要的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-