@oxios

Как не сохранять картинку если она не изменилась?

Привет!

Делаю админ панель. Я формирую формДатаи отправляю на сервер.
formData.append("headerBg", headerBg);
В роутере я делаю следущее.
Создал массив ожидаемых полей
const expectedFields = ['headerBg', 'previewImg', 'fullImg'];

И в fileFilter я добавляю в массив поля которые передаю с клиента
req.inboxFileFields.push(file.fieldname);
Так вот потом циклом прохожу по
for (let i = 0; i < expectedFields.length; i++) {
            if (!req.inboxFileFields.includes(expectedFields[i])) {
                update[expectedFields[i]] = null;
            }
        }

И я считаю если поле которое я ожидал не передали то файл нужно удалить.
Но щас получается что если у меня картинка уже загружена и я хочу поменять только текст какой-то, отправляю форму без поля с картинкой, на сервере я вижу что ожидаемое поле не передали и значить нужно его в базе удалить. но я не хочу удалять я хочу просто проигнорировать это условие, ничего с уже загруженной картинкой не делать, а поменять только текст.
Какой механизм проверки? Может мне нужно с клиента на сервер какое то доп. поле передать что бы сервер понял что эта картинка не изменилась и ее перезаписывать или удалять не нужно?

const router = require('express').Router();
const Project = require('../../../models/Project');
const multer = require('multer');
const slugify = require('slugify');
const uuidv4 = require('uuid/v4');

const allowedMimeTypes = ['image/jpeg'];
const expectedFields = ['headerBg', 'previewImg', 'fullImg'];

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, './uploads/projects');
    },
    filename: function (req, file, cb) {
        cb(null, uuidv4() + '-' + file.originalname);
    }
});

const fileFilter = (req, file, cb) => {
    req.inboxFileFields.push(file.fieldname);

    if (allowedMimeTypes.includes(file.mimetype)) {
        cb(null, true);
    } else {
        return cb({message: 'Формат файла не верный'}, false);
    }
};

const upload = multer({
    storage,
    limits: {fileSize: 1024 * 1024 * 5},
    fileFilter
}).any();

router.put('/:slug', (req, res, next) => {
    req.inboxFileFields = [];

    const {slug} = req.params;

    upload(req, res, async function (err) {

        if (err) {
            return res.status(400).json({message: err.message || 'Что-то пошло не так'});
        }

        let update = {
            ...req.body,
            slug: slugify(req.body.name, {replacement: '-', remove: null, lower: true})
        };

        req.files.forEach((file) => {
            const pathFile = `/${file.path.replace(/\\/g, '/')}`;
            const field = file.fieldname;

            update[field] = pathFile;
        });
        
        for (let i = 0; i < expectedFields.length; i++) {
            if (!req.inboxFileFields.includes(expectedFields[i])) {
                update[expectedFields[i]] = null;
            }
        }

        const newProject = await Project.findOneAndUpdate({slug}, update, {new: true});

        return res.status(202).json({newProject});
    })
});

module.exports = router;
  • Вопрос задан
  • 207 просмотров
Пригласить эксперта
Ответы на вопрос 1
GreyCrew
@GreyCrew
Full-stack developer
Вижу два варианта решенния проблемы.
1) Перекодировать изображение в base64 формат, т.е. текст, и сравнивать с оригиналом.
const bitmap = fs.readFileSync(file)
const base64Image = new Buffer(bitmap).toString('base64') // Получили изображение формата base64

2) Воспользоваться node-opencv - библиотекой для компьютерного зрения и с помощью неё сравнить 2 изображения.
В данном случае уже есть библиотека для сравнения - image-diff. Перимущество данного способа в том, что он покажет на сколько сильно поменялось изображение в отличии от оригинала.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы