【问题标题】:Image Not Uploading to Google Cloud Storage with Multer?图片未使用 Multer 上传到 Google 云存储?
【发布时间】:2019-12-19 17:03:12
【问题描述】:

编辑:找出问题,下面的解决方案。

我正在使用 multer 和 multer google storage 尝试将图像文件上传到我的 Google Cloud Bucket,但由于某种原因,这些文件没有保存到 Google Cloud Bucket 中,并且我无法记录任何错误,不知道我在这里做错了什么。 (已尝试遵循几个不同的教程,阅读文档,检查其他 SO 问题等。仍然没有解决方案)。

const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const passport = require('passport');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const multer = require('multer');
const path = require('path');
const multerGoogleStorage = require('multer-google-storage');


const { Storage } = require('@google-cloud/storage'); 

const gc = new Storage({
    projectId: '{projectIdRedacted}',
    keyFilename: path.join(__dirname, '../{keyFileNameRedacted.json}')
});

gc.getBuckets().then(x => console.log(x));

// This is showing that I've successfully paired to the Google Cloud bucket. 

const bucket = gc.bucket('{redactedBucketNameHere}');

const fileFilter = (req, file, cb) => {
    // Reject a file 
    if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
        cb(null, true);
    } else {
        cb(null, false);
    }
};


var uploadHandler = multer({ 
    storage: multer.memoryStorage(), 
    limits: {
        fileSize: 1024 * 1024 * 1
    },
    fileFilter: fileFilter
});

// Testing GCP Bucket Image Upload
// @route   POST image-upload
// @desc    Add image
// @access  Private
router.post('/image-upload', uploadHandler.single('UploadBox'), passport.authenticate('jwt', {
    session: false
}), (req, res, next) => {

    // This is showing the req.file is being passed through
    console.log(req.file);

    const blob = bucket.file(req.file.originalname);

    const blobStream = blob.createWriteStream({
        metadata: {
            contentType: req.file.mimetype
        },
        resumable: false
    });

    // The err is not getting console logged even though it is not saving to the google cloud bucket properly?
    blobStream.on('error', err => {
        next(err);
        console.log(err);
        return;
    })

    // The publicUrl is not getting console.logged - presumably cause something is breaking before this and it won't save it
    blobStream.on('finish', () => {
        // the public url can be used to directly access the file via HTTP
        const publicUrl = `https://storage.googleapis.com/${bucket.name}/${blob.name}`;
        console.log(publicUrl);

        // Make the image public to the web (since we'll be displaying it in the browser)
        blob.makePublic().then(() => {
            res.status(200).send(`Success!\n Image uploaded to ${publicUrl}`);
        })
    })
});

@google-cloud/storage 的文档是:https://www.npmjs.com/package/@google-cloud/storage multer google storage 的文档是:https://www.npmjs.com/package/multer-google-storage Google 的云存储使用指南的文档是:https://cloud.google.com/appengine/docs/flexible/nodejs/using-cloud-storage

任何提示和帮助将不胜感激。

编辑:我想出了解决方案。我不得不将uploadHandler 和fileFilter 移到const { storage} 导入之上。然后在路线内部,我必须添加“blobStream.end();”在 blobStream.on('finish') 之后。这样做后它解决了它。我已经编辑了下面的工作代码。

const express = require('express');
const router = express.Router();
const mongoose = require('mongoose');
const passport = require('passport');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const multer = require('multer');
const path = require('path');
const multerGoogleStorage = require('multer-google-storage');


const fileFilter = (req, file, cb) => {
    // Reject a file 
    if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
        cb(null, true);
    } else {
        cb(null, false);
    }
};

var uploadHandler = multer({ 
    storage: multer.memoryStorage(), 
    limits: {
        fileSize: 1024 * 1024 * 1
    },
    fileFilter: fileFilter
});


const { Storage } = require('@google-cloud/storage'); 

const gc = new Storage({
    projectId: '{projectIdRedacted}',
    keyFilename: path.join(__dirname, '../{keyFileNameRedacted.json}')
});

gc.getBuckets().then(x => console.log(x));

const bucket = gc.bucket('{bucketNameRedacted}');

// Testing GCP Bucket Image Upload
// @route   POST image-upload
// @desc    Add image
// @access  Private
router.post('/image-upload', uploadHandler.single('UploadBox'), passport.authenticate('jwt', {
    session: false
}), (req, res, next) => {

    // This is showing the req.file is being passed through
    console.log(req.file);

    const blob = bucket.file(req.file.originalname);

    const blobStream = blob.createWriteStream({
        metadata: {
            contentType: req.file.mimetype
        },
        resumable: false
    });

    // The err is not getting console logged even though it is not saving to the google cloud bucket properly?
    blobStream.on('error', err => {
        next(err);
        console.log(err);
        return;
    })

    // The publicUrl is not getting console.logged - presumably cause something is breaking before this and it won't save it
    blobStream.on('finish', () => {
        // the public url can be used to directly access the file via HTTP
        const publicUrl = `https://storage.googleapis.com/${bucket.name}/${blob.name}`;
        console.log(publicUrl);

        // Make the image public to the web (since we'll be displaying it in the browser)
        blob.makePublic().then(() => {
            res.status(200).send(`Success!\n Image uploaded to ${publicUrl}`);
        })
    })

    blobStream.end();
});

【问题讨论】:

    标签: javascript google-cloud-storage multer


    【解决方案1】:

    顺便说一句,您并不真的需要 multer-google-storage 包。

    请评论您在点击本次上传的路线时收到的响应错误消息。

    【讨论】:

    • 感谢您的回复。我让它工作了。我只是对我的一些进口/声明感到困惑。我还必须添加 blobStream.end()。我已经用解决方案编辑了我的原始帖子。不过感谢您的回复!
    • 我认为这更像是一个评论而不是一个答案。
    【解决方案2】:

    我想出了解决办法。我不得不将uploadHandler 和fileFilter 移到const { storage} 导入之上。然后在路线内部,我必须添加“blobStream.end();”在 blobStream.on('finish') 之后。这样做后它解决了它。我已经编辑了下面的工作代码。

    const express = require('express');
    const router = express.Router();
    const mongoose = require('mongoose');
    const passport = require('passport');
    const bodyParser = require('body-parser');
    const jwt = require('jsonwebtoken');
    const multer = require('multer');
    const path = require('path');
    const multerGoogleStorage = require('multer-google-storage');
    
    
    const fileFilter = (req, file, cb) => {
        // Reject a file 
        if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
            cb(null, true);
        } else {
            cb(null, false);
        }
    };
    
    var uploadHandler = multer({ 
        storage: multer.memoryStorage(), 
        limits: {
            fileSize: 1024 * 1024 * 1
        },
        fileFilter: fileFilter
    });
    
    
    const { Storage } = require('@google-cloud/storage'); 
    
    const gc = new Storage({
        projectId: '{projectIdRedacted}',
        keyFilename: path.join(__dirname, '../{keyFileNameRedacted.json}')
    });
    
    gc.getBuckets().then(x => console.log(x));
    
    const bucket = gc.bucket('{bucketNameRedacted}');
    
    // Testing GCP Bucket Image Upload
    // @route   POST image-upload
    // @desc    Add image
    // @access  Private
    router.post('/image-upload', uploadHandler.single('UploadBox'), passport.authenticate('jwt', {
        session: false
    }), (req, res, next) => {
    
        // This is showing the req.file is being passed through
        console.log(req.file);
    
        const blob = bucket.file(req.file.originalname);
    
        const blobStream = blob.createWriteStream({
            metadata: {
                contentType: req.file.mimetype
            },
            resumable: false
        });
    
        // The err is not getting console logged even though it is not saving to the google cloud bucket properly?
        blobStream.on('error', err => {
            next(err);
            console.log(err);
    
    
       return;
        })
    
    // The publicUrl is not getting console.logged - presumably cause something is breaking before this and it won't save it
    blobStream.on('finish', () => {
        // the public url can be used to directly access the file via HTTP
        const publicUrl = `https://storage.googleapis.com/${bucket.name}/${blob.name}`;
        console.log(publicUrl);
    
        // Make the image public to the web (since we'll be displaying it in the browser)
        blob.makePublic().then(() => {
            res.status(200).send(`Success!\n Image uploaded to ${publicUrl}`);
        })
    })
    
    blobStream.end();
    });
    

    【讨论】:

    • 使用此代码,我将一个文件放入我的谷歌云存储桶,但它的大小为 0KB。没有其他错误。知道如何解决这个问题吗?
    • 不幸的是,我不知道。确保您使用的是正确的文件类型并且目标位置正确。
    猜你喜欢
    • 2015-03-01
    • 2021-05-30
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    相关资源
    最近更新 更多