在未定义的数据库列中使用 express 结果以 html 形式将数据发送到 mysql 数据库

Sending data in a html form to mysql data base using express results in undefined database columns

我的主要目标是用 Node.js 创建一个 RestAPI 并在小型 HTML 应用程序中测试它。

我的老师通过示例帮助我们创建了 RestAPI,我能够将其适应我自己的 MySQL 数据库,并且我已经测试了 API 的每个端点] 在 Visual Studio 代码上使用 Thunder 客户端扩展,它工作正常。

但是我在测试 html 应用程序时遇到问题。我正在尝试使用表单发送一些数据,但在我提交时它不会保存我放入表单中的任何数据,而是将空值插入所有列。我知道端点是正确的,因为它真正连接到正确的函数和 table,并将新数据行插入到 table.

这是我的 HTML 表格

<!DOCTYPE html>

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
    <title>Header</title>

    <link rel="stylesheet" href="css/styles.css">
    </head>
<body>

    <h1 id="teste"> Adicionar um Videojogo</h1>
    <form action=" http://localhost:3000/api/videogames" method="post" enctype="multipart/form-data"  >

        <div class="form-item col" id="form_">
                    <input type="text" name= "nome" id="nome" placeholder="Nome" required= "required">
                    </div>
        <div class="form-item" id="form_">
                    <input type="text" name= "produtora" id="produtora" placeholder="Produtora" required= "required">               
                    </div>
        <div class="form-item" id="form_">
                   <input type="text" name= "distribuidora" id="distribuidora" placeholder="Distribuidora" required= "required">
                    </div>
        <div class="form-item" id="form_">
                   <input type="text" name= "ano" id="ano" placeholder="Ano" required= "required">
    
                   </div>

这是我的模型:

const sql = require("./db.js");

// construtor
const Videogame = function(videogame) {
  this.nome = videogame.nome;
  this.produtora = videogame.produtora;
  this.distribuidora = videogame.distribuidora;
  this.ano = videogame.ano;
  this.id_genero= videogame.id_genero;
  this.id_plataforma = videogame.id_plataforma;
}

Videogame.insert = (newVideogame, result) => {
  sql.query('INSERT INTO videogame SET ?', newVideogame, (err, res) => {
    if (err) {
      console.log('error: ', err);
      result(err, null);
      return;
    }

    console.log("Videojogo inserido: ", { id: res.insertId, ...newVideogame });
    result(null, { id: res.insertId, ...newVideogame});
  });
}

我的控制器:

const Videogame = require("../models/videogame.model.js");

// Inserir um novo videojogo
exports.insert = (req, res) => {
    // Validar a request
    if (!req.body) {
      res.status(400).send({
        message: "O conteúdo do videojogo deve estar definido."
      });
    }
  
    // Criar um "Videogame"
    const videogame = new Videogame({
      nome: req.body.nome,
      produtora: req.body.produtora,
      distribuidora: req.body.distribuidora,
      ano: req.body.ano,
      id_genero: req.body.id_genero,
      id_plataforma: req.body.id_plataforma,
    });
  
    // Guardar "Videogame" na base de dados
    Videogame.insert(videogame, (err, data) => {
      if (err)
        res.status(500).send({
          message:
            err.message || "Ocorreu um erro ao inserir o videojogo..."
        });
      else res.send(data);
           
    });
  };

我的路线:

module.exports = app => {
    const videogames = require("../controllers/videogame.controller.js");
  
    var router = require("express").Router();
  
    // Consultar todos os videojogos
    router.get("/", videogames.selectAll);
  
    // Consultar um videojogos pelo id
    router.get("/:id", videogames.findById);
  
    // Inserir um novo videojogo
    router.post("/", videogames.insert);
  
    // Atualizar um videojogo pelo id
    router.put("/:id", videogames.update);
  
    // Apagar um videojogo pelo id
    router.delete("/:id", videogames.delete);
  
    // Apagar todos os videojogos
    router.delete("/", videogames.deleteAll);
  
    app.use('/api/videogames', router);
  };

我的服务器:

const express = require('express');
const cors = require('cors');

const app = express();
const PORT = process.env.PORT || 3000;
const corsOptions = {
  origin: 'http://localhost'
};

app.use(cors(corsOptions));

// tratamento (parse) de pedidos de content-type - application/json
app.use(express.json());

// tratamento (parse) de pedidos de content-type - application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));

/*// route de "entrada" - apenas para efeito de teste
app.get("/", (req, res) => {
  res.json({ message: "Movies API . IPVC" });
});*/

// importação das videogames.routes com um argumento de inicialização
require('./app/routes/videogames.routes.js')(app);

// ativação do servidor, onde serão recebidos os pedidos, na porta definida
app.listen(PORT, () => {
  console.log(`Servidor ativo na porta ${PORT}.`);
});

它连接到数据库,但这里是数据库连接

const mysql = require('mysql');
const DBConfig = require('../config/db.config.js');

// Criar conexão à base de dados
const connection = mysql.createConnection({
  host: DBConfig.DBSERVER,
  user: DBConfig.DBUSER,
  password: DBConfig.DBPASS,
  database: DBConfig.DBNAME
});

// Abrir conexão à base de dados
connection.connect(error => {
  if (error) throw error;
  console.log('Ligação à base de dados estabelecida...');
});

module.exports = connection;

这是我提交表单后出现在终端上的结果

Videojogo inserido:  {
  id: 14,
  nome: undefined,
  produtora: undefined,
  distribuidora: undefined,
  ano: undefined,
  id_genero: undefined,
  id_plataforma: undefined
}

它应该保存表单中的数据而不是 undefined(我的表单中还有 id_genero 和 id_plataforma 的 2 个单选按钮,但我只把另一个在此处输入,因为我认为问题不在于单选按钮,就好像它会在表单中分配其他输入值一样。)

我不知道你是如何设置服务器的,但你应该有一个中间件来解析传入的数据。 对于 HTML 表单数据,您需要使用以下 app.use(express.urlencoded({ extended: false }));

您可以阅读 here 以了解有关 express 内置中间件及其可选属性的更多信息。

刚刚还注意到您正在使用 enctype="multipart/form-data",请问有什么原因吗?您的表单看起来很基本,因此您应该可以使用默认的 application/x-www-form-urlencoded,因此您无需指定它。

您正在使用 express.json(),但您的表单数据不是 JSON 格式。

您可以在应用程序文件夹中使用 npm 安装 express-formidable

然后你需要使用它来创建中间件,像这样:

// in app.js
const formidableMiddleware = require('express-formidable');
//...

// Note that req.fields will be instead of req.body due to middleware
// used to handle json, forms, and uploading files
app.use(formidableMiddleware(
  {
    encoding: 'utf-8',
    // means multi files (array of files) in one request
    multiples: true, 
  }
));

您需要将 app.use(express.json()); 替换为上述代码段

您还可以检查 an example from ExpressJS repo on github 的多部分表单