我可以使用multer-storage-cloudinary包成功地上传镜像,但是我还没有拼凑出如何从我的更新或删除路径中销毁cloudinary中的镜像的实现。我找到的所有资源都只是参考上传图片。这是我上传图片所需的内容
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);
});
});
下面是处理表单提交的前端代码
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);
最后是我的更新路径,它上传一个新图像并将其新路径保存到数据库中,但我也想从Cloudinary中删除旧图像,这样我就不会在那里建立未使用的工件。
router.put('/:id', withAuth, imgUpload.single('work-img'), (req, res) => {
Post.update(
{
title : req.body.title,
dimension : req.body.dimensions,
description : req.body.description,
media : req.body.media,
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);
});
});
如果我查看post路由中的console.log(req.file),它会显示如下所示
{
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'
}根据Cloudinary API文档,响应看起来与"public_id“这样的键有很大不同。
{
"public_id": "eneivicys42bq5f2jpn2",
"version": 1570979139,
"signature": "abcdefghijklmnopqrstuvwxyz12345",
"width": 1000,
"height": 672,
"format": "jpg",
"resource_type": "image",
"created_at": "2017-08-11T12:24:32Z",
"tags": [],
"bytes": 350749,
"type": "upload",
"etag": "5297bd123ad4ddad723483c176e35f6e",
"url": "http://res.cloudinary.com/demo/image/upload/v1570979139/eneivicys42bq5f2jpn2.jpg",
"secure_url": "https://res.cloudinary.com/demo/image/upload/v1570979139/eneivicys42bq5f2jpn2.jpg",
"original_filename": "sample",
"eager": [
{ "transformation": "c_pad,h_300,w_400",
"width": 400,
"height": 300,
"url": "http://res.cloudinary.com/demo/image/upload/c_pad,h_300,w_400/v1570979139/eneivicys42bq5f2jpn2.jpg",
"secure_url": "https://res.cloudinary.com/demo/image/upload/c_pad,h_300,w_400/v1570979139/eneivicys42bq5f2jpn2.jpg" },
然后,我可以将' public_id‘与destroy方法一起使用,但我不能访问public_id来配置: cloudinary.v2.uploader.destroy(public_id,options,callback);
我不清楚如何实现这一点,或者是否可以使用multer-storage-cloudinary包
发布于 2020-09-08 05:32:11
因此,对于任何可能感兴趣的人来说,我最终这样做的方式如下所示
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通常会将其添加到请求对象中。(显然,模式需要使用新的public_id字段进行更新)。在PUT回调中,查询post的db并获取旧的public_id。解析它并将其传递给cloudinay.uploader.destroy()方法。如果您的路由位于与imgUpload配置不同的文件中,则需要使用cloudinary。然后,你可以从cloudinary回调内部更新你的db,也可以不更新,因为它们不相互依赖,cloudinary操作对用户体验并不重要。
发布于 2020-09-01 07:34:55
对于删除,public_id是必需的。如果在使用multer-storage-cloudinary时没有在响应中获得public_id,您可以在上传时将其作为参数传递,这将是Cloudinary上的图像的名称。要删除图像,只需使用该public_id即可。或者,您可以使用cloudinary.uploader.upload函数,它将返回带有public_id和您在示例响应中提到的其他详细信息的JSON。
发布于 2021-10-28 17:44:49
import { v2 as cloudinary } from "cloudinary";
import express from "express";
const router = express.Router();
router.route("/delete-image").post(async (req, res, next) => {
try {
cloudinary.uploader.destroy(req.body.public_id, function (error, result) {
res.status(200).send({ result, error });
});
} catch (error) {
next(error);
}
// public_id: "folder_name/file_name" WITHOUT file extension
});
export default router;我就是这么做的。
https://stackoverflow.com/questions/63653564
复制相似问题