【问题标题】:How do I use google cloud storage as a bucket to store user/client images in a MERN Stack app?如何使用谷歌云存储作为存储桶在 MERN Stack 应用程序中存储用户/客户端图像?
【发布时间】:2020-02-05 15:28:30
【问题描述】:

我正在使用 mongoDB、express、react 和 node 开发一个漂亮的香草样板博客样式应用程序。它允许用户注册、身份验证、授权用户 CRUD 发帖、制作 cmets 和回复 cmets(到目前为止)。

我有一个定义明确的架构(使用猫鼬),User 模型有一个 avatar 字段,它应该是该用户的个人资料图片的 URI。这就是我现在所坚持的:在 Google Cloud Storage 上为用户上传的个人资料图片集成图片托管,然后获取 URL 并将其保存到 user.avatar

我已经尝试过广泛地查找这一点,但无济于事(尽管那是在我盯着屏幕看了几个小时之后的凌晨 4 点)。我真的找不到可靠的解决方案,我应该提到这是我第一次处理文件上传(我是学生,虽然这不是家庭作业问题)。

老实说,任何形式的帮助都将不胜感激。

编辑:我已尝试浏览 Google Cloud Storage 的文档。

【问题讨论】:

    标签: node.js mongodb mongoose google-cloud-storage firebase-storage


    【解决方案1】:

    https://cloud.google.com/nodejs/getting-started/using-cloud-storage 有一些很好的信息,在Upload to Cloud Storage 部分。

    function sendUploadToGCS (req, res, next) {
      if (!req.file) {
        return next();
      }
    
      const gcsname = Date.now() + req.file.originalname;
      const file = bucket.file(gcsname);
    
      const stream = file.createWriteStream({
        metadata: {
          contentType: req.file.mimetype
        },
        resumable: false
      });
    
      stream.on('error', (err) => {
        req.file.cloudStorageError = err;
        next(err);
      });
    
      stream.on('finish', () => {
        req.file.cloudStorageObject = gcsname;
        file.makePublic().then(() => {
          req.file.cloudStoragePublicUrl = getPublicUrl(gcsname); // this will be the URL you will use in your web pages
          next();
        });
      });
    
      stream.end(req.file.buffer);
    }
    

    示例还使用Multer,它是 Express 的中间件,用于处理文件上传

    【讨论】:

    • 感谢您的快速响应,我什至没有注意到该页面,我会立即尝试看看它的运行情况。
    【解决方案2】:

    根据您希望处理发生的位置,无论是在前端使用 React 还是在后端使用 Express,您都可以使用 Google Cloud 客户端库将文件上传到 GCS,然后使用 Signed URLs 或链接 URL您可以在 GCS 的 Object details 中找到并将其放在 <img src=... /> 标记中。

    例如,借助documentation,您可以上传如下文件:

    /utilities/utils.js

    const { Storage } = require('@google-cloud/storage');
    const storage = new Storage();
    
    export const uploadObject = async (bucketName, fileName) => {
      await storage.bucket(bucketName).upload(filename);
    }
    

    /routes/gcs.js

    [...]
    const { uploadObject } = require('../utilities/utils');
    
    router.post('/api/uploadAvatar', async (req, res) => {
      await uploadObject(req.body.bucketName, req.body.fileName);
    });
    

    此示例特定于您将在后端执行此类进程的情况,但如果您决定在前端执行此操作,则这些概念应适用。

    对于初学者,我建议尽早决定如何划分 React.js 代码和 Express.js 代码。您想使用microservices-like architecture 并在后端(服务器端处理)中为大多数任务使用 React 调用 REST 端点并将客户端处理保持在最低限度吗?或者您只是想使用您的后端与 mongodb 通信并在 React 中执行大多数进程?那里有很多可行的架构,我邀请您提前制定一个周密的计划!

    【讨论】:

    • 我确实计划将客户端负载保持在最低限度,因此必须在服务器上完成。不过我会试试的,谢谢。
    • 太好了,告诉我进展如何。
    • 所以我基本上尝试了我在他们的文档中可以找到的所有内容,但结果却反复出现以下错误:Error: The project to be billed is associated with an absent billing account 这是我确定该项目与非常当前的帐单相关联的时候帐户。 sigh 我将尝试改用 AWS S3。这有点令人失望,因为我真的很想使用 GCP。
    • 您是否检查过您指定的存储桶是否存在?指定不存在的存储桶时经常会弹出该错误,单击(打开云存储浏览器)蓝色按钮并检查here,或者如果您用完了Cloud Storage Always Free usage limits,我认为这里不会出现这种情况你刚开始。无论如何,如果您想进一步解决此问题,我非常愿意提供帮助。
    • 很高兴为您提供帮助,祝您在未来的努力中好运!
    猜你喜欢
    • 2016-03-21
    • 1970-01-01
    • 2018-04-21
    • 1970-01-01
    • 2015-02-18
    • 2018-11-04
    • 1970-01-01
    • 2017-11-23
    • 2019-05-08
    相关资源
    最近更新 更多