【问题标题】:Upload image in sql with express in nodejs用nodejs中的express在sql中上传图像
【发布时间】:2019-01-21 15:18:39
【问题描述】:

我是节点的新手,我遇到了一些麻烦。我在节点中使用 express,并尝试将图像作为 base64 上传到 sql DB 中的 blob。如果图片小于 50kb,则上传 else got

PayloadTooLargeError:请求实体太大。

我试过了:

error-request-entity-too-large

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

没有什么对我有用,或者我做错了什么。有人能帮我吗?

代码:

crud.js(将方法转换为 vue2)

    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>.


【问题讨论】:

  • 不要将图像存储在数据库中,将图像存储在数据库中是一种不好的做法。您所做的是将它们存储在某个文件系统(您的服务器、S3 等)上,并将路径存储在您的数据库中。
  • 感谢您的提示,不知道这是一种不好的做法。你说做stackoverflow.com/questions/20213400/…之类的事情这是一个了解nodejs的测试,但是当我去开发生产时,图像无法在任何驱动器中访问。
  • 这很简单,但是可以。如果符合您的要求,您可以将文件存储在您的服务器上,或者将其移动到其他地方,但仅将此类文件的路径存储在您的数据库中,而不是全部内容。

标签: node.js express vuejs2


【解决方案1】:

要使用 express 上传文件,您应该使用 multer lib。 这是因为 express 和 body 解析器处理表单数据。 Multer 是上传文件时处理 multipart-formdata 的正确方法。

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
})

您应该会在 uploads 文件夹中看到上传的文件。

如果您想保存在 Postgres 数据库中,您应该使用 Bytea 列来保存您的数据。 在进行选择时,您应该select encode(data, 'base64') from filmes where id = $id

您的表单应具有以下属性,enctype="multipart/form-data" 以便 multer 知道要从您的数据中处理什么。

在您的html标签内,属性名称应与multer上传路由中声明的相同。:

<form action="/action_page_binary.asp" method="post" enctype="multipart/form-data">
 <input type="file" id="file" name="avatar" multiple>
</form>

【讨论】:

  • 感谢您的回答,也会看到 multer。这个方法就像埃里克·鲁伊斯·德查韦斯说的那样?将链接保存在BD中,并将图像存储在存储中。
  • 不,不是。它将文件中的数据保存在数据库内的表中。
  • Danizavtz,req.file 中的内容 "{"fieldname":"imagem","originalname":"IMG_20180720_182341.jpg","encoding":"7bit","mimetype":"image /jpeg","destination":"uploads/","filename":"98e686d701b47363ffcc484080005a27","path":"uploads/98e686d701b47363ffcc484080005a27","size":85512}" 会保存在BD中吗?全部?此方法将文件的副本保存在 /uploads 中,并将路径保存在 req.file 中。我在使用mariaDB,要使用什么类型的BLOB?以及如何从选择中检索数据?从 id = $id 的电影中使用 select encode(imagem, 'base64'), column1, column2。抱歉打扰你了,但我迷路了。
  • 你应该保存req.file.buffer就是你要保存的数据。
  • 做 console.log(JSON.stringify(req.file.buffer)) 显示未定义,我在对象 req.file "{"fieldname":"imagem"," originalname":"IMG_20180720_182341.jpg","encoding":"7bit","mimetype":"image/jpeg","destination":"uploads/","filename":"98e686d701b47363ffcc484080005a27","path":"uploads /98e686d701b47363ffcc484080005a27","size":85512}" .
【解决方案2】:

我解决了在节点上上传图像文件的问题。问题是我已经在 app.js 中使用了 bodyParser 并尝试在 index.js 中修改它,我只需要在 bodyParser json 中插入限制并在 app.js 中进行 urlencoded(而不是在 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

与:

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

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

也可以。而在 DB 中,您必须使用 longBlob 字段,否则您将无法获得完整的图像。

感谢 Erick Ruiz de Chavez(我很快就会看到你的方法)和 Danizavtz 帮助我学习。

【讨论】:

    猜你喜欢
    • 2012-07-17
    • 2017-07-23
    • 1970-01-01
    • 2020-04-29
    • 2020-06-28
    • 2020-01-31
    • 2021-07-04
    • 2023-03-03
    • 2021-03-03
    相关资源
    最近更新 更多