如何解决如何使用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);
});
});
{
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 举报,一经查实,本站将立刻删除。