如何在cloudinary上直接上传图片而不存储到本地目录?

How to upload images directly on cloudinary without storing it into local directory?

我是 ExpressJs 的新手,正在为在 reactjs 中创建的仪表板之一创建 api。仪表板中有一个表格,它从用户那里收集一些信息,如“标题”、“描述”和“图像”。我创建了一个快速服务器来收集该信息并将其保存到 mongodb。对于图像我所做的是,我将图像上传到 Cloudinary 并将上传的 url 和 public_id 存储到数据库中。

所以在学习了一些教程之后,我做了这样的事情。

index.js

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");

const db = require("./db");

// Api router import goes here
const sectionTypesRouter = require("./routes/section-types-router");

const app = express();
const apiPort = 3000;

app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.use(bodyParser.json());

db.on("error", console.error.bind(console, "MongoDB connection error:"));

app.get("/", (req, res) => {
  res.send("Hello World!");
});

app.use("/api", sectionTypesRouter);

app.listen(apiPort, () => console.log(`Server running on port ${apiPort}`));

然后,首先我创建了一个文件 multer.js :

const multer = require("multer");

const storage = multer.diskStorage({
  destination: "public/uploads",
  filename: (req, file, cb) => {
    cb(null, file.fieldname + "-" + Date.now());
  },
});

const fileFilter = (req, file, cb) => {
  if (file.mimetype === "image/jpeg" || file.mimetype === "image/png") {
    cb(null, true);
  } else {
    //reject file
    cb({ message: "Unsupported file format" }, false);
  }
};

const upload = multer({
  storage: storage,
  fileFilter: fileFilter,
});

module.exports = upload;

下面是我的 api 路由器 section-type-router.js :

const express = require("express");
const upload = require("../utils/multer");

const SectionTypesCtrl = require("../controllers/section-types-ctrl");

const router = express.Router();

router.post(
  "/section-type",
  upload.single("image"),
  SectionTypesCtrl.createSectionType
);
router.get("/section-types", SectionTypesCtrl.getSectionTypes);

module.exports = router;

这是section-type-ctrl.js:

const SectionType = require("../models/section-type-model");
const fs = require("fs");
const path = require("path");
const cloudinaryUploader = require("../utils/cloudinaryUploader");

const createSectionType = async (req, res) => {
  const body = req.body;

  if (!body) {
    return res.status(400).json({
      success: false,
      error: "Required parameter are missing",
    });
  }
  cloudinaryUploader
    .uploads(req.file.path, "Section-Types")
    .then((result) => {
      const sectionType = new SectionType({
        title: body.title,
        description: body.description,
        image: {
          url: result.url,
          publicId: result.public_id,
        },
      });
      sectionType
        .save()
        .then(() => {
          return res.status(201).json({
            success: true,
            id: sectionType._id,
            message: "Section type created!",
          });
        })
        .catch((error) => {
          return res.status(400).json({
            error,
            message: "Section type not created!",
          });
        });
    })
    .catch((error) => {
      res.status(500).send({
        message: "failure",
        error,
      });
    });
};

module.exports = {
  createSectionType,
};

最后是 cloudinaryUpload.js :

const cloudinary = require("../config/cloudinary");

exports.uploads = (file, folder) => {
  return new Promise((resolve) => {
    cloudinary.uploader.upload(
      file,
      {
        resource_type: "auto",
        folder: folder,
      },
      (err, result) => {
        if (!err) {
          resolve({
            url: result.url,
            public_id: result.public_id,
          });
        } else {
          throw err;
        }
      }
    );
  }).catch((error) => {
    throw error;
  });
};

现在,一切正常。图像正在上传到 cloudinary 并返回 url 并且 public_id 存储在数据库中。但问题是我上传的 图片也在本地目录 public/uploads/ 上上传。这可能会在托管网站时产生存储问题。那么有什么最好的方法可以将图像直接上传到 cloudinary 而无需在本地目录中创建副本,这也应该适用于生产模式?

在您的示例中,文件正在存储到您服务器上的 public/uploads,因为您通过 multer.diskStorage

告诉 multer 这样做

正如上面@Molda 的评论所说,您可以通过使用 multer-storage-cloudinary 包让 Multer 自动将文件存储在 Cloudinary 中来避免这种情况。

另一种可能性是更改您使用 Multer 的方式,使其不会将文件存储在任何地方,然后在上传的文件在内存中时将其作为流传递给 Cloudinary 的 SDK。

Cloudinary 网站上的博客 post 中有一个这样的示例:https://cloudinary.com/blog/node_js_file_upload_to_a_local_server_or_to_the_cloud

在您的情况下,您可以停止使用 multer.diskStorage,转而使用 multer(),然后使用 streamifier 或其他库将上传的文件转换为流,并将其传递给 cloudinary.uploader.upload_stream()