在 MERN stack Web 应用程序中存储图像的最佳方式

Cro*_*roc 8 mongodb node.js firebase reactjs mern

我正在使用 MERN 堆栈(MongoDB、Express Server、ReactJS 前端和 NodeJS 后端)构建一个 Web 应用程序,并且想知道一些从后端存储图像的好方法。

过去,我直接从前端使用 Firebase 进行身份验证和存储。由于我正在 MongoDB 中处理我自己的用户身份验证模型,是否仍然可以使用 firebase 存储,如果可以的话,它会来自前端还是后端。如果它来自前端,我如何在没有 Firebase 身份验证的情况下保护它?

我读过的其他选项是使用 GridFS 将图像存储到 MongoDB 中或使用 Multer 存储在服务器上。

一旦我心中有了解决方案,我将能够阅读文档并找出如何完成它。

任何建议表示赞赏。

Han*_*dev 5

一个选项是将图像上传到客户端的Cloudinary ,并使用您自己的 API 将返回的 URL 保存到 MongoDB。Cloudinary 不仅可以托管图像,还可以处理图像操作和优化等。

基本上你需要做的是:

  1. 注册一个 Cloudinary 帐户
  2. 转到设置 -> 上传
  3. 添加带有“未签名模式”的“上传预设”,以启用未签名上传到 Cloudinary

那么你的上传函数可以是这样的:

async function uploadImage(file) { // file from <input type="file"> 
  const data = new FormData();
  data.append("file", file);
  data.append("upload_preset", NAME_OF_UPLOAD_PRESET);

  const res = await fetch(
    `https://api.cloudinary.com/v1_1/${YOUR_ID}/image/upload`,
    {
      method: "POST",
      body: data,
    }
  );
  const img = await res.json();
  // Post `img.secure_url` to your server and save to MongoDB
}
Run Code Online (Sandbox Code Playgroud)

  • 你好@FrazerFindlater,你可以看看我整理的这个[codesandbox](https://codesandbox.io/s/react-cloudinary-demo-dn2ho-sre1u)。 (2认同)

Cro*_*roc 3

我最终从 Firebase Admin SDK 实现了 Firebase 存储,并使用 Multer 将图像存储在内存中,直到将它们加载到 Firebase。

https://firebase.google.com/docs/storage/admin/start

const uploader = multer({
  storage: multer.memoryStorage(),
  limits: {
    fileSize: 5 * 1024 * 1024,
  },
});


// @route   POST api/users/upload/avatar
// @desc    Upload a new avatar and save to storage
// @access  Private
router.post('/upload/avatar', [auth, uploader.single('image')], async (req, res, next) => {
  if (!req.file) {
    res.status(400).json({ msg: 'No file submitted.' });
    return;
  }

  try {
    const blob = firebase.bucket.file(req.file.originalname);
    const blobStream = blob.createWriteStream({
      gzip: true,
      resumable: false,
      metadata: {
        contentType: req.file.mimetype,
      },
    });

    blobStream.on('error', (err) => next(err));

    blobStream.on('finish', () => {
      publicUrl = `https://firebasestorage.googleapis.com/v0/b/${
        firebase.bucket.name
      }/o/${encodeURI(blob.name)}?alt=media`;

      res.status(200).json({
        photoURL: publicUrl,
      });

      User.findById(req.user.id).then((user) => {
        user.photoURL = publicUrl;
        user.save();
      });
    });

    blobStream.end(req.file.buffer);
  } catch (error) {
    console.error(error.message);
    res.status(500).send({ msg: 'A Server error occurred' });
  }
});
Run Code Online (Sandbox Code Playgroud)

我认为如果将来有人偶然发现这篇文章,这可能会有所帮助。