Как сделать так, чтобы изображение, хранящееся в mongodb с multer, показывалось на странице при запросе его с сервера? - PullRequest
0 голосов
/ 21 апреля 2020

Итак, я успешно использовал multer для загрузки изображений на mongodb, но проблема в том, что я не знаю, как заставить их показываться на странице.

const [selectedFile, setSelectedFile] = React.useState(getUser().avatar);
// getUser() function is returning the logged user from localStorage

const fileSelectedHandler = evt => setSelectedFile(evt.target.files[0]);

const uploadProfileImage = async (evt) => {
        evt.preventDefault();

        const formData = new FormData();
        formData.append('image', selectedFile);
        const config = {
            headers: {
                'content-type': 'multipart/form-data',
            },
        };

        await axios.put(`http://localhost:8080/avatar/${id}`, formData, config)
            .then(response => {
                localStorage.setItem(localStorageName, JSON.stringify({ ...getUser(), avatar: response.data.user.avatar }));
            }).catch(error => console.log(error));

    }

настройки multer в контроллере маршрута

const multer = require('multer');
const DIRECTORY = './uploads/images';

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, DIRECTORY);
    },
    filename: function (req, file, cb) {
        cb(null, `IMAGE-${Date.now()}.${path.extname(file.originalname)}`);
    },
});

const upload = multer({
    // storage: storage,
    storage: multer.memoryStorage(),
    fileFilter: (req, file, cb) => {
        if (file.mimetype == 'image/png' || file.mimetype == 'image/jpg' || file.mimetype == 'image/jpeg') {
            cb(null, true);
        } else {
            cb(null, false);
            return cb(new Error('Only .png, .jpg and .jpeg format allowed!'));
        }
    },
    limits: { fileSize: 1024 * 1024 * 2 },
});

файл маршрута загрузки изображения

router.put('/avatar/:uid', upload.single('image'), avatar);

Все это успешно сохраняет буфер изображения в mongodb:

{ ... аватар: "очень длинная строка" ...}

Но проблема в том, что я не знаю, как заставить это изображение показываться на веб-странице.

<img src={getUser().avatar} />

<a  href="#">
    <form onSubmit={uploadProfileImage}>
        <input type="file" name="image" onChange={fileSelectedHandler} />
        <button type="submit">Upload</button>
    </form>
    <span>Add Photo</span>
</a>

сервер загрузки изображений

const avatar = (req, res) => {
    const image = req.file.buffer.toString('base64');

    User.findByIdAndUpdate(req.params.uid, { $set: { avatar: image }}, { new: true, upsert: true })
        .exec((error, user) => {
            if (error) {
                return res.status(400).json({
                    message: error.message,
                });
            }

            console.log(req.file)

            res.status(201).json({
                message: 'Avatar added successfully',
                user
            });
        });
};

1 Ответ

0 голосов
/ 21 апреля 2020

Настоятельно не рекомендуется хранить изображения в MongoDB. Но если вы действительно хотите это сделать, вам придется конвертировать изображение в base64; и для его рендеринга у вас должно быть что-то вроде <img src="data:image/png;base64, base64codeHere" alt="Red dot" />.

Тем не менее, лучший подход заключается в том, что вы храните изображение где-то локально и сохраняете путь только в MongoDB.

Поэтому, когда вы хотите отрендерить, просто укажите путь к атрибуту src в теге <img>.

Пример:

//Multer DiskStorage Config
const diskStorage = multer.diskStorage({
    destination: 'assets/pic_upload',
    filename: (req, file, call_back) => {

        //Prepend date to the filename or anything that makes the 
        //File unique so it won't get overwritten
        call_back(null, Date.now() + '_' + file.originalname);
    }

});

//Create Multer Instance
const upload = multer({ storage: diskStorage });

//Picture upload
router.post('/upload--pic', upload.single('file'), (req, res) => {


    //Example DB code from my project. Feel free to 
    //apply your own logic here
    //Update the pic in the DB
    User_DB.findOneAndUpdate({ _id: 'idHere' }, {

        //Store the pic path in the DB
        profImage: (req.file.path).replace('assets/', '')

    })

});

At the front end you will need something like this:

 <form action="/pic_upload" enctype="multipart/form-data"> </form>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...