-1

I'm newbie in node and I'm having a little trouble. I'm using express in node, and trying to upload a image as a base64 for blob in sql DB. If the image is under 50kb, upload else got

PayloadTooLargeError: request entity too large.

I have tried:

error-request-entity-too-large

request-entity-too-large-how-to-increase-bodyparser-limit

And nothing worked for me or am I doing anything wrong. Can someone help me?

The code:

crud.js (converting to vue2 the methods)

    const app = new Vue({
        el: "#main",
        data:{
            id_filme: 2,
            titulo: "",
            imagem: "",
            lancamento: "",
            avaliacao: ""
        },
        mounted(){

        },
        watch:{

        },
        computed:{

        },
        methods:{
            getDados(){

            },
            editar(){
                axios.post('/atualizar/'+ this.id_filme, {
                    id_filme: this.id_filme,
                    titulo: this.titulo,
                    imagem: this.imagem,
                    lancamento: this.lancamento,
                    avaliacao: this.avaliacao

                })
                  .then(function (res) {
                    console.log(res);
                  })
                  .catch(function (error) {
                    // alert("Erro","Ocorreu um erro de servidor, entrar em contato com o analista responsável.","error") 
                    alert("Erro") 
                    console.error('falhou verifique a informação', error); 
                  });
            },
            encodeImageFileAsURL() {
                document.getElementById("capa").innerHTML = "";
                var filesSelected = document.getElementById("imagem").files;
                if (filesSelected.length > 0) {
                    var fileToLoad = filesSelected[0];
                    // console.log(fileToLoad)
                    var fileReader = new FileReader();
                    fileReader.onload = function(fileLoadedEvent) {
                        var srcData = fileLoadedEvent.target.result; // <--- data: base64
                        var newImage = document.createElement('img');
                        newImage.src = srcData;
                        app.imagem = srcData

                        document.getElementById("capa").innerHTML = newImage.outerHTML;
                    }
                    console.log(app.imagem)
                    fileReader.readAsDataURL(fileToLoad);
                }
            }
        }
    })

index.js


    'use strict'

    const   filmes = require('../models/filmes'),
            express = require('express'),
            bodyParser = require('body-parser')
    const erro404 = (req, res, next) => {
        let erro = new Error(),
            locals = {
                titulo: "Erro",
                descricao: "Página não encontrada !",
                contato: "Entre em contato com o administrador do sistema.",
                erro: erro
            }
        erro.status = 404
        res.render('erro.jade', locals)
        next()
    }

    var app = express()

    app
        .use(bodyParser.json({limit: '50mb'}))    
        .use(bodyParser.urlencoded({
            limit: '50mb',
            extended: true,
            parameterLimit:50000
          }))

        .use(filmes)

        .get('/', (req, res, next) => {
            req.getConnection((err, filmes) => {
                filmes.query('SELECT * FROM filmes', (err, rows) =>{
                    if (err){
                        next(new Error('Não há filmes.'))
                    }else{
                        let locals = {
                            principal: 'Lista de Filmes',
                            dados: rows
                        }
                        res.render('index', locals)
                    }
                })
            })
            //next()
        })

        .get('/add', (req,res, next) => {
            res.render('add_filmes.jade', {principal: 'Lista de Filmes', titulo: 'Adicionar Filme'})
        })

        .post('/', (req, res, next) => {
            req.getConnection((err, filmes) => {
                let filme = {
                    id_filme: req.body.id_filme,
                    titulo: req.body.titulo,
                    lancamento: req.body.lancamento,
                    avaliacao: req.body.avaliacao,
                    imagem: req.body.imagem
                }

                console.log(filme)

                filmes.query('INSERT INTO filmes SET ?', filme, (err, rows) =>{
                    return (err) ? next(new Error('Erro ao inserir o filme.')) : res.redirect('/')
                })
            })
        })

        .get('/editar/:id_filme', (req, res, next) => {
            let id_filme = req.params.id_filme

            console.log(id_filme)

            req.getConnection((err, filmes) => {
                filmes.query('SELECT * FROM filmes WHERE id_filme = ?', id_filme, (err, rows) => {
                    console.log(err, "---", rows)
                    if(err){
                        next(new Error('Erro ao pegar os dados do filme.'))
                    }else{
                        let locals = {
                            principal: 'Lista de Filmes', 
                            titulo: 'Editar Filme',
                            dados: rows
                        }

                        res.render('editar_filme.jade', locals)

                    }
                })
            })

        })

        .post('/atualizar/:id_filme', (req, res, next)=>{
            console.log(JSON.stringify(req.body))
            req.getConnection((err, filmes) => {
                let filme = {
                    id_filme: req.body.id_filme,
                    titulo: req.body.titulo,
                    lancamento: req.body.lancamento,
                    avaliacao: req.body.avaliacao,
                    imagem: req.body.imagem
                }

                console.log(filme)

                filmes.query('UPDATE filmes SET ? WHERE id_filme = ?', [filme, filme.id_filme], (err, rows) =>{
                    return (err) ? next(new Error('Erro ao atualizar o filme.')) : res.redirect('/')
                })
            })
        })

        .post('/excluir/:id_filme', (req, res, next)=>{
            let id_filme = req.params.id_filme

            console.log(id_filme)

            req.getConnection((err, filmes) => {
                filmes.query('DELETE FROM filmes WHERE id_filme = ?', id_filme, (err, rows) => {
                    console.log(err, "---", rows)
                    return (err) ? next(new Error('Registro não encontrado !')) : res.redirect('/')
                })
            })
        })

        .use(erro404)


    module.exports = app

```

<b>Thanks in advance.</b>.


Georgia
  • 1,183
  • 8
  • 19
Maknollram
  • 33
  • 8
  • Do not store images on your DB, storing images in a DB is a bad practice. What you do is to store them on a file system somewhere (your server, S3, etc.) and store the path on your DB. – Erick Ruiz de Chavez Aug 14 '18 at 18:54
  • Thanks for the tip, don't know it's a bad practice. You say do something like https://stackoverflow.com/questions/20213400/storing-the-location-of-the-images-in-the-database-using-varchar-in-expressjs This one is a test to know nodejs, but when i go to develop the production the image can't be acessed in any drive. – Maknollram Aug 14 '18 at 19:01
  • That is a simple one but yes. You can store the file on your server if that is ok with your requirements, or move it somewhere else, but only store the path to such file in your DB, not the whole content. – Erick Ruiz de Chavez Aug 14 '18 at 19:07

2 Answers2

0

To upload files using express you should use multer lib. It happens because express and body parser process form-data. Multer is the proper way to handle multipart-formdata when uploading files.

var express = require('express')
var multer  = require('multer')
var upload = multer({ dest: 'uploads/' })
app.post('/profile', upload.single('avatar'), function (req, res, next) {
  // após fazer esse request voce deve ver no req.file o arquivo que deseja salvar
  // req.body possuirá os outros atributos que não são multipart formdata
})

you should see the file inside the uploads folder the files uploaded.

If you want to save in the Postgres database you should use a column Bytea to hold your data. and when doing the select you should select encode(data, 'base64') from filmes where id = $id

Your form should have the following attribute, enctype="multipart/form-data" for multer to know what to proccess from your data.

Inside the tag from your html the attribute name should be the same as declared in multer upload route.:

<form action="/action_page_binary.asp" method="post" enctype="multipart/form-data">
 <input type="file" id="file" name="avatar" multiple>
</form>
Danizavtz
  • 2,498
  • 3
  • 21
  • 19
  • Thanks for the answer, will see the multer too. This method is like Erick Ruiz de Chavez said? Save the link in BD and store the image in the storage. – Maknollram Aug 15 '18 at 10:32
  • no, its not. its saving the data from files in a table inside the database. – Danizavtz Aug 15 '18 at 12:14
  • Danizavtz, what from the req.file "{"fieldname":"imagem","originalname":"IMG_20180720_182341.jpg","encoding":"7bit","mimetype":"image/jpeg","destination":"uploads/","filename":"98e686d701b47363ffcc484080005a27","path":"uploads/98e686d701b47363ffcc484080005a27","size":85512}" will be saved in the BD? All? This method save a copy of the file in /uploads and have the path in req.file. I'm using mariaDB, what is the type to be used BLOB? And how can I retrieve the data from a select? Using select encode(imagem, 'base64'), column1, column2 from filmes where id = $id. Sorry annoy you, but I'm lost. – Maknollram Aug 15 '18 at 16:55
  • you should save the req.file.buffer is the data you want to save. – Danizavtz Aug 15 '18 at 17:24
  • Doing console.log(JSON.stringify(req.file.buffer)) show undefined, I don't find buffer in the object req.file "{"fieldname":"imagem","originalname":"IMG_20180720_182341.jpg","encoding":"7bit","mimetype":"image/jpeg","destination":"uploads/","filename":"98e686d701b47363ffcc484080005a27","path":"uploads/98e686d701b47363ffcc484080005a27","size":85512}" . – Maknollram Aug 15 '18 at 18:00
  • Maybe if you declare your multer class without a destination the object buffer will appear in the req.file.buffer. Currently its. being saved in the uploads folder. – Danizavtz Aug 15 '18 at 18:16
  • Removing the dest from "upload = multer()" gives the buffer and don't save a copy of the file, I saved as BLOB and in DB I can see the image if click in blob link, but my table don't take it. The select encode(imagem, 'base64'), column1, column2 from filmes where id = $id don't return the data. Did you can help with this too? – Maknollram Aug 15 '18 at 18:37
  • I never used mariadb, the sql script I gave you, is from a Postgres database example, which has these functions to manipulate data and transform in base64 the image. I can't help you with the specific part of the mariadb. – Danizavtz Aug 15 '18 at 19:11
  • Thanks anyway, will try the method Erick Ruiz said too. – Maknollram Aug 15 '18 at 21:14
0

I solved my problem with uploading the image files on the node. the problem was that I was already using a bodyParser in app.js and tried to modify it in index.js, I only have to insert the limit in bodyParser json and urlencoded in app.js (not in index.js)



    'use strict'

    ////variáveis globais////
    const   express = require('express'),
            // path = require('path'),
            favicon = require('serve-favicon'),
            bodyParser = require('body-parser'),
            morgan = require('morgan'),
            jade = require('jade'),

            routes = require('./routes/index'),
            publicDir = express.static(`${__dirname}/public`),
            viewDir = `${__dirname}/views`,
            port = (process.env.PORT || 3000),
            app = express(),

            faviconURL = `${__dirname}/public/img/nodeFavicon.png`

    app
        ////configurando app////
        .set('views', viewDir)
        //engine de html
        .set('view engine', 'jade')
        .set('port', port)

        ////executando middlewares////
        .use(favicon(faviconURL))

        // para dar parse nos dados para json
        .use(bodyParser.json({limit:1024*1024*20, type:'application/json'}))

        // dá um parse nos dados do form no tipo application/x-www-form-urlencoded
          .use(bodyParser.urlencoded({extended:true,limit:1024*1024*20,type:'application/x-www-form-urlencoded' }))

        //middleware que é um logger, como se fosse o network do navegador
        .use(morgan('dev'))
        .use(publicDir)

        //executa os middlewares das rotas
        .use(routes)

    module.exports = app

with:

.use(bodyParser.json({limit: "50mb"}))

.use(bodyParser.urlencoded({limit: "50mb", extended: true, parameterLimit:50000}))

works too. And in DB you have to use a longBlob field or you don't will get the full image.

Thanks to Erick Ruiz de Chavez (I will see your method soon) and Danizavtz for help me with my study.

Maknollram
  • 33
  • 8