Express、Multer 和 Cloudinary 没有返回完整的 cloudinary 响应
Express, Multer, and Cloudinary not returning full cloudinary response
我正在使用 Multer/multer-storage-cloudinary 将图像直接上传到 Cloudinary,而不是先将其上传到本地临时目录,然后再发送到 Cloudinary:
const express = require('express');
const router = express.Router({mergeParams:true});
if (app.get('env') == 'development'){ require('dotenv').config(); }
const crypto = require('crypto');
const cloudinary = require('cloudinary').v2;
const { CloudinaryStorage } = require('multer-storage-cloudinary');
const multer = require('multer');
const { storage } = require('../cloudinary');
const upload = multer({storage});
//configure cloudinary upload settings
cloudinary.config({
cloud_name:process.env.CLOUDINARY_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET
});
const storage = new CloudinaryStorage({
cloudinary: cloudinary,
folder: ('book_tracker/'+process.env.CLOUDINARY_FOLDER+'posts'),
allowedFormats: ['jpeg', 'jpg', 'png'],
filename: function (req, file, cb) {
let buf = crypto.randomBytes(16);
buf = buf.toString('hex');
let uniqFileName = file.originalname.replace(/\.jpeg|\.jpg|\.png/ig, '');
uniqFileName += buf;
console.log(req.body);
cb(undefined, uniqFileName );
}
});
const middleware = {
function asyncErrorHandler: (fn) =>
(req, res, next) => {
Promise.resolve(fn(req, res, next))
.catch(next);
}
}
/* POST create user page */
router.post('/register', upload.single('image'), asyncErrorHandler(postRegister));
我 运行 的是,我在 req.file
中得到的响应不是完整的 Cloudinary 响应,其中包括 public_id 等。相反,它是这样的:
{
fieldname: 'image',
originalname: 'My Headshot.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
path: 'https://res.cloudinary.com/<cloudinary_name>/image/upload/v1611267647/<public_id>.jpg',
size: 379632,
filename: '<public_id>'
}
自从我使用 multer-storage-cloudinary 以来已经有一段时间了,尽管 storage
是直接从一个旧项目中获取的,该项目会 return 正确的信息。 multer 或 multer-storage-cloudinary 中是否有我需要设置的东西,以便将完整的 cloudinary 响应放入 req.file?
multer-storage-cloudinary
包是第三方包,以简化的方式集成了 multer 和 Cloudinary,但它没有公开 Cloudinary SDK 或 API[= 的所有可能选项或响应22=]
在您的示例中,它不会返回来自 Cloudinary 的完整 API 响应,而是返回字段的子集,因为 file
对象的 filename
、path
、和 size
属性取自 Cloudinary API 响应(分别来自 API 响应的 public_id
、secure_url
和 bytes
属性) ,但未映射其他字段:https://github.com/affanshahid/multer-storage-cloudinary#file-properties
如果您需要全套响应值(或一些尚未映射的特定值),您可以:
- 请求包维护者添加对其他字段的支持
- 自己分叉包并映射其他字段;虽然我不确定还需要更改哪些字段,但这些字段已映射到此处:https://github.com/affanshahid/multer-storage-cloudinary/blob/1eb903d44ac6dd42eb1ab655b1e108acd97ed4ca/src/index.ts#L83-L86
- 不再使用该包来包装 Cloudinary SDK,而是直接在您自己的代码中使用 Cloudinary SDK,这样您就可以直接处理响应。
- 保持原样并单独调用 Cloudinary Admin API 以获取图像的其他详细信息:https://cloudinary.com/documentation/admin_api#get_resources
- 保持原样,但添加 notification_url 以便与 API 调用响应一样,新上传的详细信息将在 HTTP POST 中发送请求您选择的URL:https://cloudinary.com/documentation/notifications
- notification_url 可以在上传 API 调用、上传预设或 Cloudinary 帐户设置中的帐户级别指定。
我正在使用 Multer/multer-storage-cloudinary 将图像直接上传到 Cloudinary,而不是先将其上传到本地临时目录,然后再发送到 Cloudinary:
const express = require('express');
const router = express.Router({mergeParams:true});
if (app.get('env') == 'development'){ require('dotenv').config(); }
const crypto = require('crypto');
const cloudinary = require('cloudinary').v2;
const { CloudinaryStorage } = require('multer-storage-cloudinary');
const multer = require('multer');
const { storage } = require('../cloudinary');
const upload = multer({storage});
//configure cloudinary upload settings
cloudinary.config({
cloud_name:process.env.CLOUDINARY_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET
});
const storage = new CloudinaryStorage({
cloudinary: cloudinary,
folder: ('book_tracker/'+process.env.CLOUDINARY_FOLDER+'posts'),
allowedFormats: ['jpeg', 'jpg', 'png'],
filename: function (req, file, cb) {
let buf = crypto.randomBytes(16);
buf = buf.toString('hex');
let uniqFileName = file.originalname.replace(/\.jpeg|\.jpg|\.png/ig, '');
uniqFileName += buf;
console.log(req.body);
cb(undefined, uniqFileName );
}
});
const middleware = {
function asyncErrorHandler: (fn) =>
(req, res, next) => {
Promise.resolve(fn(req, res, next))
.catch(next);
}
}
/* POST create user page */
router.post('/register', upload.single('image'), asyncErrorHandler(postRegister));
我 运行 的是,我在 req.file
中得到的响应不是完整的 Cloudinary 响应,其中包括 public_id 等。相反,它是这样的:
{
fieldname: 'image',
originalname: 'My Headshot.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
path: 'https://res.cloudinary.com/<cloudinary_name>/image/upload/v1611267647/<public_id>.jpg',
size: 379632,
filename: '<public_id>'
}
自从我使用 multer-storage-cloudinary 以来已经有一段时间了,尽管 storage
是直接从一个旧项目中获取的,该项目会 return 正确的信息。 multer 或 multer-storage-cloudinary 中是否有我需要设置的东西,以便将完整的 cloudinary 响应放入 req.file?
multer-storage-cloudinary
包是第三方包,以简化的方式集成了 multer 和 Cloudinary,但它没有公开 Cloudinary SDK 或 API[= 的所有可能选项或响应22=]
在您的示例中,它不会返回来自 Cloudinary 的完整 API 响应,而是返回字段的子集,因为 file
对象的 filename
、path
、和 size
属性取自 Cloudinary API 响应(分别来自 API 响应的 public_id
、secure_url
和 bytes
属性) ,但未映射其他字段:https://github.com/affanshahid/multer-storage-cloudinary#file-properties
如果您需要全套响应值(或一些尚未映射的特定值),您可以:
- 请求包维护者添加对其他字段的支持
- 自己分叉包并映射其他字段;虽然我不确定还需要更改哪些字段,但这些字段已映射到此处:https://github.com/affanshahid/multer-storage-cloudinary/blob/1eb903d44ac6dd42eb1ab655b1e108acd97ed4ca/src/index.ts#L83-L86
- 不再使用该包来包装 Cloudinary SDK,而是直接在您自己的代码中使用 Cloudinary SDK,这样您就可以直接处理响应。
- 保持原样并单独调用 Cloudinary Admin API 以获取图像的其他详细信息:https://cloudinary.com/documentation/admin_api#get_resources
- 保持原样,但添加 notification_url 以便与 API 调用响应一样,新上传的详细信息将在 HTTP POST 中发送请求您选择的URL:https://cloudinary.com/documentation/notifications
- notification_url 可以在上传 API 调用、上传预设或 Cloudinary 帐户设置中的帐户级别指定。