Aplicación Web para la I.4.0

— Alfredo de Jesús Gutiérrez Gómez, Dr

Index

Presentación

1.  Piense en el nombre de un animal que inicie con la primera letra de su nombre.

2. Este no deberá repetirse.

3. Al presentarse deberá completar la siguiente frase: Mi nombre es: _______ y he venido sobre un/a: _______ a la escuela desde _____

4. Dar respuesta a las preguntas:

4.1  ¿Porqué estudio está carrera?

4.2  ¿Qué me ha gustado de la carrera hasta ahora?

Temas del curso

Unidad 1.

Comunicación Segura

  1. Manejo de sesiones
  2. Seguridad en las transacciones

Temas del curso

Unidad 2.

Framework para web empresarial

  1. Frameworks de desarrollo.
  2. Instalación del Framework.
  3. Configuración de las aplicaciones

Temas del curso

Unidad 3.

Desarrollo MVC (modelo, vista, controlador).

  1. Modelo
  2. Vista
  3. Controlador

Políticas de clase

  • Teléfono móvil en modo silencio.
  • Las llamadas urgentes /prio se contestan fuera del salón.
  • Turnos de una sola persona para ir al WC.
  • Dos faltas a la semana sin justificante perderían derecho a las cuestiones de aprendizaje.
  • Levantar la mano para participar.
  • Respetar la participación de cada alumno.

Lineamiento de clase

  • Mantenerse informado acerca de las lecturas, actividades y tareas del curso asistiendo por lo menos dos veces por semana, durante la duración del curso.
  • Cumplir dentro del aula virtual con todas las tareas, foros y actividades detalladas por el programa académico y el profesor, en el tiempo y forma establecidos.
  • El incumplimiento de las tareas en tiempo y forma llevarán a una no aprobación del curso.

Lineamiento de clase

  • Realizar el seguimiento personal desde el Aula Virtual.

  • Estar pendiente de los resultados de las evaluacion/es parcial/es y final/es.

  • Notificar al tutor por escrito, con copia a la coordinación académica, si, por alguna razón excepcional, se encontrara en una circunstancia especial que le impidiera continuar con el curso y recibir así indicaciones de cómo proceder a partir de ese momento.

Descripción de las actividades

Unidad 1

  • Cuestionario de aprendizaje
  • Caso de estudio

Unidad 2

  • Cuestionario de aprendizaje
  • Caso de estudio

Descripción de las actividades

Unidad 3

  • Cuestionario de aprendizaje
  • Estudio de caso

Descripción de las actividades

Actividades

Actividades de encuadre

Actividad

En una hoja escribe la respuesta a la siguiente pregunta:

 

  1. ¿Qué esperas que se enseñe en este curso?
  2. ¿A qué te comprometes en este curso?
  3. ¿Qué deseas aprender en este curso?

 

Una vez contestadas las preguntas pulsa aquí para agregarte al grupo y sube tus respuesta.

Recomendaciones

Se enumeran las recomendaciones que se deben seguir para la realización de las actividades

Trabajos:

Recomendaciones

  • Portada
  • Presentación
  • Introducción
  • Conclusión

Párrafos:

  • Mayores a tres líneas
  • Menores a ocho líneas
  • Coherencia entre párrafos

Ortografía:

Recomendaciones

  • Acentuación en mayúsculas y minúsculas.
  • Evitar redundancia.
  • Evitar pleonasmos.
  • Mínimo tres errores.

Referencia bibliográfica:

  • Al menos tres citas dentro del trabajo.
  • En formato APA 7ma edición.

Lista de referencias bibliográfica

Recomendaciones

  • Al menos tres fuentes de diversos autores.
  • Con sangría francesa al inicio de cuatro espacios.
  • Fuente Times New Roman.
  • 12 puntos.
  • Sin enlaces activos.

Introducción y conclusión

  • Mínimo tres párrafos

Formato del trabajo:

Recomendaciones

  • Fuente Arial.
  • Tamaño de título: 14 puntos.
  • Tamaño de texto: 12 puntos.
  • Interlineado 1.5
  • Alineación justificada del texto.
  • Los títulos alineados a la izquierda.
  • En el encabezado del documento colocar el logotipo del instituto alineado a la derecha. Nombre de la carrera a la izquierda.

Tablas:

Recomendaciones

  • Colocarle al pie de la tabla un nombre a la tabla, bajo el siguiente formato:  <nombre_tabla numero consecutivo>. <nombre_tabla> <fuente:> <donde_fue_tomada> .
  • Colocar un párrafo descriptivo

Imágenes / diagramas / gráficas:

Recomendaciones

  • Colocarle al pie de la tabla un nombre a la tabla, bajo el siguiente formato:  <nombre_tabla numero consecutivo>. <nombre_tabla> <fuente:> <donde_fue_tomada> .
  • Colocar un párrafo descriptivo

¿Dudas?

Unidad I

Comunicación Segura

Fundamental en la transmisión de datos para evitar accesos no autorizados, garantizar la integridad de la información y proteger la privacidad.

U1 > Comunicación Segura

Los protocolos y técnicas utilizados aseguran que los datos intercambiados entre usuarios o sistemas sean confidenciales y estén a salvo de ataques.

Técnica utilizada para mantener la continuidad de las interacciones de un usuario con un sistema o aplicación web. 

U1 > Comunicación Segura

Manejo de Sesiones

Una sesión es una conexión establecida entre un cliente (generalmente un navegador) y un servidor, donde se guarda información temporal para identificar al usuario y su estado durante su interacción.

Sesión

U1 > Comunicación Segura

Manejo de Sesiones

Las cookies almacenan el session ID y otra información que ayuda a recordar al usuario.

Es un conjunto de interacciones de un usuario con una aplicación dentro de un período específico.

Identificador de sesión (session ID)

Un valor único asignado a cada sesión, que puede ser almacenado en cookies, URL, o variables de sesión.

Gestión de cookies

Fijación de sesión

U1 > Comunicación Segura

Manejo de Sesiones

Un atacante fuerza a un usuario a utilizar un session ID conocido por él.

Secuestro de sesión (session hijacking)

Cuando un atacante roba un session ID válido para suplantar al usuario.

U1 > Comunicación Segura

Manejo de Sesiones

Usar identificadores de sesión seguros, generados de forma aleatoria.

Utilizar el protocolo HTTPS para proteger los datos de sesión.

Configurar el vencimiento automático de sesiones después de un tiempo de inactividad.

U1 > Comunicación Segura

Manejo de Sesiones

  • Cuando inicias sesión en un sitio web de banca en línea, el servidor crea una sesión para tu cuenta.
  • Si cierras la pestaña sin cerrar la sesión, la información de la sesión puede permanecer activa por un tiempo definido o hasta que cierres la sesión manualmente.

U1 > Comunicación Segura

Manejo de Sesiones

Actividad de aprendizaje

Pulsa aquí para resolver la actividad o scanea el qr

U1 > Comunicación Segura

Seguridad en la Transmisión

Asegura que la información que viaja entre el emisor y el receptor no sea interceptada o modificada por terceros malintencionados.

U1 > Comunicación Segura

Seguridad en la Transmisión

Garantiza que la información no ha sido alterada durante la transmisión.

Cifrado (encryption)

Técnica que convierte los datos en un formato ilegible sin una clave específica para descifrarlos.

Autenticación

Verifica la identidad del remitente y el destinatario

Integridad de datos

U1 > Comunicación Segura

Seguridad en la Transmisión

HTTPS (Hypertext Transfer Protocol Secure)

Protocolo que utiliza SSL/TLS para cifrar la comunicación web.

TLS (Transport Layer Security)

Protocolo criptográfico para asegurar las conexiones a través de redes.

U1 > Comunicación Segura

Seguridad en la Transmisión

Ataque Man-in-the-Middle (MitM)

Un atacante intercepta la comunicación entre dos partes para robar o manipular datos.

Sniffing

Escucha pasiva de datos transmitidos para obtener información sensible.

U1 > Comunicación Segura

Seguridad en la Transmisión

Cuando accedes a una tienda en línea para realizar una compra, el sitio debe usar HTTPS para cifrar la información de tu tarjeta de crédito y protegerla de ser robada por atacantes durante la transmisión.

U1 > Comunicación Segura

Seguridad en la Transmisión

Actividad de aprendizaje

Pulsa aquí o escanea el qr

U1 > Comunicación Segura

the code

Para establecer una comunicación segura entre un cliente y un servidor, se utiliza el protocolo HTTPS, que cifra los datos transmitidos.

U1 > Comunicación Segura

the code

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('key.pem'),  // Clave privada
  cert: fs.readFileSync('cert.pem') // Certificado
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('Conexión segura establecida');
}).listen(8443, () => {
  console.log('Servidor HTTPS ejecutándose en https://localhost:8443');
});

U1 > Comunicación Segura

the code

  • key.pem y cert.pem son archivos necesarios para la autenticación SSL/TLS.
  • https.createServer crea un servidor seguro que cifra la comunicación.
  • Los navegadores confían en certificados emitidos por una autoridad de certificación (CA), pero para pruebas locales puedes usar certificados autogenerados.

Buenas Prácticas

  1. No expongas los certificados en repositorios públicos.
  2. Protege el acceso a los archivos de clave privada (key.pem) restringiendo los permisos del sistema de archivos.

U1 > Comunicación Segura

the code

Ejecutando el código:

  • Abre una terminal y ejecuta:
    • node nombre_fichero.js

 

U1 > Comunicación Segura

the code

openssl req -nodes -new -x509 -keyout key.pem -out cert.pem
  • openssl: Llama a la herramienta.
  • req: Solicita la creación de un certificado.
  • -nodes: Indica que no se debe cifrar la clave privada con una contraseña.
  • -new: Genera una nueva solicitud de firma de certificado (CSR).
  • -x509: Crea un certificado autofirmado.
  • -keyout key.pem: Guarda la clave privada en el archivo key.pem.
  • -out cert.pem: Guarda el certificado en el archivo cert.pem.

U1 > Comunicación Segura

the code

Campos a llenar en el comando OpenSSL:

Country Name (2 letter code) [XX]:
Código de dos letras del país (ISO 3166).

MX (México), US (Estados Unidos), ES (España)

State or Province Name (full name) [Some-State]:
El nombre completo del estado o provincia.

Jalisco, California, Tabasco

Locality Name (eg, city) [Some-City]:
El nombre de la ciudad o localidad.

Guadalajara, Madrid, Villahermosa

U1 > Comunicación Segura

the code

Campos a llenar en el comando OpenSSL:

Organization Name (eg, company) [Internet Widgits Pty Ltd]:
El nombre de tu organización o empresa.

Empresa SA de CV

Organizational Unit Name (eg, section) []:
La unidad dentro de la organización (opcional).

Departamento de TI

U1 > Comunicación Segura

the code

Campos a llenar en el comando OpenSSL:

Common Name (e.g. server FQDN or YOUR name) []:
El nombre común es crítico. Debe ser el nombre de dominio completo (FQDN) del servidor o el nombre que usará para acceder al certificado.

localhost (para desarrollo)  
www.ejemplo.com (para producción)

Email Address []:
Dirección de correo electrónico de contacto. Este campo es opcional.

demo@prueba.com (para caso de pruebas locales)

U1 > Comunicación Segura

¿openssl?

 Certificados SSL/TLS autogenerados se suele utilizar OpenSSL, que es una herramienta de línea de comandos disponible en la mayoría de los sistemas operativos (linux o macosx)

U1 > Comunicación Segura

Openssl en win2

  • Visita el sitio slprowed. Pulsa aquí para ir. Descarga e instala.
  • Agrega la ruta de OpenSsl a las variables de entorno:
    • Valida la ruta de instalación, suele ser algo como: c:/ProgramFile/OpenSSL-Win64/bin.
      • Verifica que contenga el archivo openssl.exe.
    • Ve a menú inicio > "Editar las variables de entorno del sistema"
    • Pulsa en "Variables de entorno" > selecciona la variable "Path" > editar
    • Pulsa Nuevo > agrega la ruta donde esta instalado openssl (c:/ProgramFile/OpenSSL-Win64/bin).
    • Pulsa en aceptar. 
  • Valida la instalación
    • abre una terminal (cmd o powershel) y ejecuta
      • openssl versión (Si todo salió bien debe de mostrar la versión instalada).

U1 > Comunicación Segura

Openssl en linux

  • Abre una terminal
    • sudo apt update
    • sudo apt upgrade -y
    • sudo apt install openssl

Para distribuciones derivadas de debian (*.deb)

  • Abre una terminal
    • sudo dnf update
    • sudo dnf upgrade -y
    • sudo dnf install openssl

Para distribuciones derivadas de Redhat (*.rpm)

U1 > Comunicación Segura

Openssl en MacOsX

Ejecuta el comando: brew install openssl

U1 > Comunicación Segura

Actividad de Aprendizaje

Pulsa aquí o escanea el qr

Una web en node.js

El ambiente

  • Crea una carpeta para el proyecto
  • Entra en la carpeta creada
  • Una vez dentro de la carpeta inicializa el proyecto con node.js
$ mkdir webnode
$ cd webnode
$ npm init -y

Una web en node.js

las dependencias (framework)

  • Se suele usar express para el desarrollo de aplicaciones web. 
$ npm install express

Una web en node.js

El servidor web

  • Cree un bloc de notas con el nombre: servidor.js
  • Dentro de fichero anterior coloque el siguiente código
// Importa el módulo HTTP de Node.js
const http = require('http');
// Crea un servidor HTTP
const server = http.createServer((req, res) => {
    // Configura el código de estado y el tipo de contenido
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/html');
    // Envía una respuesta HTML
    res.end(`
        <!DOCTYPE html>
        <html lang="es">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Mi Página Web</title>
        </head>
        <body>
            <h1>¡Hola, Mundo!</h1>
            <p>Esta es mi primera página web con Node.js.</p>
        </body>
        </html>
    `);
});
// Define el puerto en el que escuchará el servidor
const port = 3000;
// Inicia el servidor
server.listen(port, () => {
    console.log(`Servidor corriendo en http://localhost:${port}/`);
});

Una web en node.js

ejecutando el server

  • En la terminal ejecute el siguiente cómando
$ node servidor.js

Una web en node.js

las rutas

¿Rutas?

  • Definen cómo un servidor maneja diferentes peticiones HTTP (GET, POST, PUT, DELETE) y responde al cliente.
  • Son los caminos que los usuarios pueden seguir en una aplicación web o API.
  • Permiten definir qué hacer cuando alguien visita una URL específica.

Ejemplo sencillo: Cuando se entra a https://www.ejemplo.com/contacto, el servidor detecta la ruta /contacto y responde con una página o información específica.

Una web en node.js

las rutas

Rutas -> ejemplos

  • GET /usuarios → Devuelve una lista de usuarios.
  • POST /usuarios → Agrega un nuevo usuario.
  •  GET /usuarios/5 → Devuelve los datos del usuario con ID 5.

Una web en node.js

las rutas

Rutas -> ejemplos

const express = require("express");
const app = express();

app.use(express.json()); // Middleware para leer JSON

// Ruta principal (Home)
app.get("/", (req, res) => {
    res.send("¡Bienvenido a mi servidor en Node.js!");
});

// Ruta para obtener todos los usuarios (GET)
app.get("/usuarios", (req, res) => {
    res.json([
        { id: 1, nombre: "Juan" },
        { id: 2, nombre: "Maria" }
    ]);
});

// Ruta para agregar un usuario (POST)
app.post("/usuarios", (req, res) => {
    const nuevoUsuario = req.body;
    res.json({ mensaje: "Usuario agregado", usuario: nuevoUsuario });
});

// Ruta con parámetros (obtener un usuario por ID)
app.get("/usuarios/:id", (req, res) => {
    res.json({ id: req.params.id, nombre: "Ejemplo" });
});

// Iniciar el servidor en el puerto 3000
app.listen(3000, () => {
    console.log("Servidor corriendo en http://localhost:3000");
});

Una web en node.js

las rutas

Rutas -> ejemplos

  • http://localhost:3000/usuarios → Devuelve una lista de usuarios.
  •  http://localhost:3000/usuarios/5 → Devuelve el usuario con ID 5.

Una web en node.js

las rutas

el código anterior, simplemente responde siempre con el nombre "Ejemplo" sin importar qué ID pases en la URL.

const express = require("express");
const app = express();

app.use(express.json()); // Middleware para leer JSON

// Lista de usuarios simulada
const usuarios = [
    { id: 1, nombre: "Juan" },
    { id: 2, nombre: "Maria" }
];

// Ruta para obtener todos los usuarios
app.get("/usuarios", (req, res) => {
    res.json(usuarios);
});

// Ruta con parámetros para obtener un usuario por ID
app.get("/usuarios/:id", (req, res) => {
    const usuario = usuarios.find(u => u.id === parseInt(req.params.id));

    if (!usuario) {
        return res.status(404).json({ mensaje: "Usuario no encontrado" });
    }

    res.json(usuario);
});

// Iniciar el servidor
app.listen(3000, () => {
    console.log("Servidor corriendo en http://localhost:3000");
});

Una web en node.js

las rutas

el código anterior, simplemente responde siempre con el nombre "Ejemplo" sin importar qué ID pases en la URL.

const express = require("express");
const app = express();

app.use(express.json()); // Middleware para leer JSON

// Lista de usuarios simulada
const usuarios = [
    { id: 1, nombre: "Juan" },
    { id: 2, nombre: "Maria" }
];

// Ruta para obtener todos los usuarios
app.get("/usuarios", (req, res) => {
    res.json(usuarios);
});

// Ruta con parámetros para obtener un usuario por ID
app.get("/usuarios/:id", (req, res) => {
    const usuario = usuarios.find(u => u.id === parseInt(req.params.id));

    if (!usuario) {
        return res.status(404).json({ mensaje: "Usuario no encontrado" });
    }

    res.json(usuario);
});

// Iniciar el servidor
app.listen(3000, () => {
    console.log("Servidor corriendo en http://localhost:3000");
});

Una web en node.js

las rutas

const http = require('http');

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/html');

    // Manejo de rutas
    if (req.url === '/') {
        res.end(`
            <h1>Inicio</h1>
            <p>Bienvenido a la página de inicio.</p>
        `);
    } else if (req.url === '/about') {
        res.end(`
            <h1>Acerca de</h1>
            <p>Esta es la página "Acerca de".</p>
        `);
    } else {
        res.statusCode = 404;
        res.end(`
            <h1>404 - Página no encontrada</h1>
            <p>Lo sentimos, la página que buscas no existe.</p>
        `);
    }
});

const port = 3000;
server.listen(port, () => {
    console.log(`Servidor corriendo en http://localhost:${port}/`);
});

Rutas sin express

Una web en node.js

las rutas

const express = require('express');
const app = express();
const port = 3000;

// Ruta de inicio
app.get('/', (req, res) => {
    res.send(`
        <h1>Inicio</h1>
        <p>Bienvenido a la página de inicio.</p>
    `);
});

// Ruta "Acerca de"
app.get('/about', (req, res) => {
    res.send(`
        <h1>Acerca de</h1>
        <p>Esta es la página "Acerca de".</p>
    `);
});

// Manejo de errores 404
app.use((req, res) => {
    res.status(404).send(`
        <h1>404 - Página no encontrada</h1>
        <p>Lo sentimos, la página que buscas no existe.</p>
    `);
});

// Inicia el servidor
app.listen(port, () => {
    console.log(`Servidor corriendo en http://localhost:${port}/`);
});

Rutas con express

Una web en node.js

La estructura

proyectoWeb/
├── public/
│   ├── index.html
│   ├── about.html
│   └── styles.css
├── server.js
└── package.json

Una web en node.js

La estructura

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Inicio</title>
</head>
<body>
    <h1>Inicio</h1>
    <p>Bienvenido a la página de inicio.</p>
</body>
</html>

Código de ejemplo de index.html

Una web en node.js

La estructura

const express = require('express');
const app = express();
const path = require('path');
const port = 3000;

// Sirve archivos estáticos desde la carpeta "public"
app.use(express.static(path.join(__dirname, 'public')));

// Inicia el servidor
app.listen(port, () => {
    console.log(`Servidor corriendo en http://localhost:${port}/`);
});

Código de ejemplo de server.js

Una web en node.js

Actividad de aprendizaje

  • Googlea Frexus.
  • Selecciona la opción: Generando Valor Agregado.
  • Ve a la sección de academia.
  • Busca el nombre de la materia y has clic en ella
  • En la sección de recursos lee el que tiene el nombre de: la reserva.

Una web en node.js

Formularios

Se utilizará Express, un framework popular para construir aplicaciones web en Node.js. Junto a  EJS como motor de plantillas para renderizar el formulario en el frontend.

Una web en node.js

Formularios

El proyecto

mkdir formulario-nodejs
cd formulario-nodejs
npm init -y

>

Una web en node.js

Formularios

Las dependencias

npm install express ejs

>

Instala Express y EJS

Una web en node.js

Formularios

La estructura

formulario-nodejs/
├── views/
│   ├── index.ejs
│   └── resultado.ejs
├── app.js
└── package.json

>

Dentro de la carpeta del proyecto, valida que exista la siguiente estructura

Una web en node.js

Formularios

El server

const express = require('express');
const app = express();
const port = 3000;

// Configurar EJS como motor de plantillas
app.set('view engine', 'ejs');
app.set('views', './views');

// Middleware para parsear el cuerpo de las solicitudes
app.use(express.urlencoded({ extended: true }));

// Ruta para mostrar el formulario
app.get('/', (req, res) => {
    res.render('index');
});

// Ruta para manejar el envío del formulario
app.post('/submit', (req, res) => {
    const { nombre, email } = req.body;
    res.render('resultado', { nombre, email });
});

// Iniciar el servidor
app.listen(port, () => {
    console.log(`Servidor corriendo en http://localhost:${port}`);
});

>

Abre el archivo app.js y configura el servidor Express

Una web en node.js

Formularios

La vista

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Formulario</title>
</head>
<body>
    <h1>Formulario de Contacto</h1>
    <form action="/submit" method="POST">
        <label for="nombre">Nombre:</label>
        <input type="text" id="nombre" name="nombre" required>
        <br>
        <label for="email">Email:</label>
        <input type="email" id="email" name="email" required>
        <br>
        <button type="submit">Enviar</button>
    </form>
</body>
</html>

>

Crear views/index.ejs, contendrá el formulario HTML

Una web en node.js

Formularios

El proceso

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Resultado</title>
</head>
<body>
    <h1>Datos Recibidos</h1>
    <p><strong>Nombre:</strong> <%= nombre %></p>
    <p><strong>Email:</strong> <%= email %></p>
    <a href="/">Volver al formulario</a>
</body>
</html>

>

Crear views/resultado.ejs, mostrará los datos enviados por el formulario:

Una web en node.js

Formularios

La ejecución

node app.js

>

Iniciar el servidor: En la terminal, ejecuta el siguiente comando para iniciar el servidor

Una web en node.js

Base de datos

Relacionales

>

Una base de datos ligera que no requiere un servidor separado. Se require el paquete sqlite3 para interactuar con ella.

MySQL

Una de las bases de datos relacionales más populares. El paquete mysql o mysql2 para conectarte desde Node.js.

PostgreSQL

Otra base de datos relacional muy potente. Se utiliza el paquete pg para conectarte desde Node.js

SQLite

Una web en node.js

Base de datos

NoSql

>

MongoDB

Base de datos NoSQL muy popular que almacena datos en formato JSON-like (BSON). Usa el paquete mongoose o mongodb para conectarte desde Node.js

Redis

Una base de datos clave-valor en memoria, útil para casos de uso específicos como caché o almacenamiento temporal. Se usa el paquete redis para interactuar con ella.

Una web en node.js

Base de datos

Configuración

>

mkdir mi-proyecto-mysql
cd mi-proyecto-mysql

Crea una carpeta para el proyecto

Una web en node.js

Base de datos

Configuración

>

npm init -y

Inicializa el proyecto

Una web en node.js

Base de datos

Configuración

>

npm install express mysql2

Instala las librerías y dependencias

Una web en node.js

Base de datos

Configuración

>

npm install nodemon --save-dev

Instala nodemon, reinicia automáticamente el servidor cuando se hacen cambios. Se suele instalar como dependencia de desarrollo: 

Una web en node.js

Base de datos

Configuración

>

mi-proyecto-mysql/
├── public/
│   └── index.html
├── src/
│   ├── config/
│   │   └── db.js
│   ├── controllers/
│   │   └── formController.js
│   ├── routes/
│   │   └── formRoutes.js
│   └── app.js
└── package.json

Valida que se tenga la siguiente estructura de folders

Una web en node.js

Base de datos

Configuración

>

CREATE DATABASE form_node;

Crear una base de datos y una tabla

USE form_node;

Selecciona la base de datos

Una web en node.js

Base de datos

Configuración

>

CREATE TABLE formulario (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(255) NOT NULL,
  email VARCHAR(255) NOT NULL,
  mensaje TEXT NOT NULL
);

Crea la tabla

Una web en node.js

Base de datos

La conexión

>

const mysql = require('mysql2');

const connection = mysql.createConnection({
  host: 'localhost',      // Dirección del servidor MySQL
  user: 'root',           // Usuario de MySQL
  password: 'tu_contraseña', // Contraseña de MySQL
  database: 'form_node' // Nombre de la base de datos
});

connection.connect((err) => {
  if (err) {
    console.error('Error conectando a la base de datos:', err);
    return;
  }
  console.log('Conectado a la base de datos MySQL');
});

module.exports = connection;

Crear el archivo src/config/db.js:

Este archivo contendrá la configuración de la conexión a MySQL.

Una web en node.js

Base de datos

El servidor

>

const express = require('express');
const bodyParser = require('body-parser');
const formRoutes = require('./routes/formRoutes');

const app = express();
const port = 3000;

// Middleware para parsear el cuerpo de las solicitudes
app.use(bodyParser.urlencoded({ extended: true }));

// Servir archivos estáticos desde la carpeta "public"
app.use(express.static('public'));

// Usar las rutas definidas en formRoutes.js
app.use('/', formRoutes);

// Iniciar el servidor
app.listen(port, () => {
  console.log(`Servidor corriendo en http://localhost:${port}`);
});

Crear el archivo src/app.js

Este es el punto de entrada del servidor.

Una web en node.js

Base de datos

La Ruta

>

const express = require('express');
const formController = require('../controllers/formController');

const router = express.Router();

// Ruta para manejar el envío del formulario
router.post('/enviar-formulario', formController.enviarFormulario);

module.exports = router;

Crear el archivo src/routes/formRoutes.js

Define las rutas para manejar el envío del formulario.

Una web en node.js

Base de datos

El envio

>

const connection = require('../config/db');

exports.enviarFormulario = (req, res) => {
  const { nombre, email, mensaje } = req.body;

  const query = 'INSERT INTO formulario (nombre, email, mensaje) VALUES (?, ?, ?)';
  connection.query(query, [nombre, email, mensaje], (err, results) => {
    if (err) {
      console.error('Error insertando datos:', err);
      res.status(500).send('Error al guardar los datos');
      return;
    }
    res.send('Datos guardados correctamente');
  });
};

Crear el archivo src/controllers/formController.js

Contiene la lógica para guardar los datos en MySQL.

Una web en node.js

Base de datos

El formulario

>

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Formulario</title>
</head>
<body>
  <h1>Formulario de contacto</h1>
  <form action="/enviar-formulario" method="POST">
    <label for="nombre">Nombre:</label>
    <input type="text" id="nombre" name="nombre" required>
    <br>
    <label for="email">Email:</label>
    <input type="email" id="email" name="email" required>
    <br>
    <label for="mensaje">Mensaje:</label>
    <textarea id="mensaje" name="mensaje" required></textarea>
    <br>
    <button type="submit">Enviar</button>
  </form>
</body>
</html>

Crear el archivo public/index.html

Este es el formulario que el usuario verá y enviará.

Una web en node.js

Base de datos

La ejecución

>

npm run dev

Si se instalo nodemon

De lo contrario

npm start

Una web en node.js

Base de datos

El error

>

Si surge un error como el que se muestra a continuación

Es porque en el fichero package.json no se ha especificado cual es la ruta a ejecutar en modo producción o desarrollo

Una web en node.js

Base de datos

La corrección

>

Para corregir el error hay que colocar las siguientes líneas dentro de la sección "scripts" del fichero package.js

  "scripts": {
    "start": "node src/app.js",
    "dev": "nodemon src/app.js"
  },

Una web en node.js

Base de datos

La corrección

>

El fichero completo

{
  "name": "form_node",
  "version": "1.0.0",
  "main": "public/index.js",
  "scripts": {
    "start": "node src/app.js",
    "dev": "nodemon src/app.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "type": "commonjs",
  "description": "",
  "dependencies": {
    "express": "^4.21.2",
    "mysql2": "^3.12.0"
  },
  "devDependencies": {
    "nodemon": "^3.1.9"
  }
}

Una web en node.js

Base de datos

La ejecución

>

Si todo ha salido bien después de ejecutar el comando

npm run dev

Debe de visualizarse una ventana como la siguiente

Después de llenar el formulario debe de mostrarse el siguiente mensaje

Una web en node.js

Base de datos

La revisión

>

Ahora se corrobora que se haya guardado los datos en mysql

Una web en node.js

Base de datos

El CRuD

>

Se creará la carpeta models dentro del directorio src

mkdir models

Dentro de models se creara un fichero Formulario.js

const connection = require('../config/db');

class Formulario {
  // Crear un nuevo registro
  static crear(nombre, email, mensaje, callback) {
    const query = 'INSERT INTO formulario (nombre, email, mensaje) VALUES (?, ?, ?)';
    connection.query(query, [nombre, email, mensaje], callback);
  }

  // Leer todos los registros
  static leerTodos(callback) {
    const query = 'SELECT * FROM formulario';
    connection.query(query, callback);
  }

  // Leer un registro por ID
  static leerPorId(id, callback) {
    const query = 'SELECT * FROM formulario WHERE id = ?';
    connection.query(query, [id], callback);
  }

  // Actualizar un registro
  static actualizar(id, nombre, email, mensaje, callback) {
    const query = 'UPDATE formulario SET nombre = ?, email = ?, mensaje = ? WHERE id = ?';
    connection.query(query, [nombre, email, mensaje, id], callback);
  }

  // Eliminar un registro
  static eliminar(id, callback) {
    const query = 'DELETE FROM formulario WHERE id = ?';
    connection.query(query, [id], callback);
  }
}

module.exports = Formulario; // Exporta la clase Formulario

Una web en node.js

Base de datos

El CRuD

>

Se modificara el fichero /src/routes/formRoutes.js

const express = require('express');
const formController = require('../controllers/formController');

const router = express.Router();

// Ruta para manejar el CRUD
router.post('/formularios', formController.crearFormulario); //crear
router.get('/formularios', formController.leerFormularios); // leer todos
router.get('/formularios/:id', formController.leerFormularioPorId); //lee uno
router.put('/formularios/:id', formController.eliminarFormulario); //eliminar


module.exports = router;

Una web en node.js

Base de datos

El CRuD

>

Se modificara el fichero /src/controllers/formController.js

const Formulario = require('../models/Formulario');

exports.crearFormulario = (req, res) => {
  const { nombre, email, mensaje } = req.body;
  Formulario.crear(nombre, email, mensaje, (err, results) => {
    if (err) {
      console.error('Error creando el registro:', err);
      res.status(500).send('Error al crear el registro');
      return;
    }
    res.status(201).send('Registro creado correctamente');
  });
};

exports.leerFormularios = (req, res) => {
  Formulario.leerTodos((err, results) => {
    if (err) {
      console.error('Error leyendo los registros:', err);
      res.status(500).send('Error al leer los registros');
      return;
    }
    res.status(200).json(results);
  });
};

exports.leerFormularioPorId = (req, res) => {
  const { id } = req.params;
  Formulario.leerPorId(id, (err, results) => {
    if (err) {
      console.error('Error leyendo el registro:', err);
      res.status(500).send('Error al leer el registro');
      return;
    }
    if (results.length === 0) {
      res.status(404).send('Registro no encontrado');
      return;
    }
    res.status(200).json(results[0]);
  });
};

exports.actualizarFormulario = (req, res) => {
  const { id } = req.params;
  const { nombre, email, mensaje } = req.body;
  Formulario.actualizar(id, nombre, email, mensaje, (err, results) => {
    if (err) {
      console.error('Error actualizando el registro:', err);
      res.status(500).send('Error al actualizar el registro');
      return;
    }
    res.status(200).send('Registro actualizado correctamente');
  });
};

exports.eliminarFormulario = (req, res) => {
  const { id } = req.params;
  Formulario.eliminar(id, (err, results) => {
    if (err) {
      console.error('Error eliminando el registro:', err);
      res.status(500).send('Error al eliminar el registro');
      return;
    }
    res.status(200).send('Registro eliminado correctamente');
  });
};

Una web en node.js

Base de datos

El CRuD

>

Se modificara el fichero /src/app.js

const express = require('express');
const bodyParser = require('body-parser');
const formRoutes = require('./routes/formRoutes');

const app = express();
const port = 3000;

// Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true}));
app.use(express.static('public'));

// Usar las rutas definidas en formRoutes.js
app.use('/', formRoutes);

// Iniciar el servidor
app.listen(port, () => {
  console.log(`Servidor corriendo en http://localhost:${port}`);
});

Una web en node.js

Base de datos

El CRuD

>

Se modificara el fichero /public/index.html

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CRUD con Node.js y MySQL</title>
</head>
<body>
  <h1>CRUD con Node.js y MySQL</h1>

  <!-- Formulario para crear registros -->
  <h2>Crear Registro</h2>
  <form id="form-crear">
    <label for="nombre">Nombre:</label>
    <input type="text" id="nombre" name="nombre" required>
    <br>
    <label for="email">Email:</label>
    <input type="email" id="email" name="email" required>
    <br>
    <label for="mensaje">Mensaje:</label>
    <textarea id="mensaje" name="mensaje" required></textarea>
    <br>
    <button type="submit">Crear</button>
  </form>

  <!-- Lista de registros -->
  <h2>Registros Existentes</h2>
  <ul id="lista-registros"></ul>

  <!-- Script para manejar el CRUD desde el frontend -->
  <script>
    // Función para cargar y mostrar los registros
    async function cargarRegistros() {
      const response = await fetch('/formularios');
      const registros = await response.json();
      const lista = document.getElementById('lista-registros');
      lista.innerHTML = registros.map(registro => `
        <li>
          ID: ${registro.id} | Nombre: ${registro.nombre} | Email: ${registro.email} | Mensaje: ${registro.mensaje}
          <button onclick="eliminarRegistro(${registro.id})">Eliminar</button>
          <button onclick="editarRegistro(${registro.id})">Editar</button>
        </li>
      `).join('');
    }

    // Función para crear un registro
    document.getElementById('form-crear').addEventListener('submit', async (e) => {
      e.preventDefault();
      const nombre = document.getElementById('nombre').value;
      const email = document.getElementById('email').value;
      const mensaje = document.getElementById('mensaje').value;

      await fetch('/formularios', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ nombre, email, mensaje })
      });

      cargarRegistros();
    });

    // Función para eliminar un registro
    async function eliminarRegistro(id) {
      await fetch(`/formularios/${id}`, { method: 'DELETE' });
      cargarRegistros();
    }

    // Función para editar un registro (puedes implementarla si lo necesitas)
    async function editarRegistro(id) {
      const nuevoNombre = prompt('Nuevo nombre:');
      const nuevoEmail = prompt('Nuevo email:');
      const nuevoMensaje = prompt('Nuevo mensaje:');

      await fetch(`/formularios/${id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ nombre: nuevoNombre, email: nuevoEmail, mensaje: nuevoMensaje })
      });

      cargarRegistros();
    }

    // Cargar registros al iniciar la página
    cargarRegistros();
  </script>
</body>
</html>

Una web en node.js

Base de datos

El CRuD

>

Se ejecuta con el comando:

npm run dev

Se deberá mostrar algo como esto en la terminal

Una web en node.js

Base de datos

El CRuD

>

En el navegador algo como esto

Una web en node.js

Base de datos

bootstrap

>

Para agregar bootstrap al proyecto se puede hacer de diferentes maneras, como:

  • cdn,
  • con los ficheros locales y como
  • dependencia del proyecto

Una web en node.js

Base de datos

bootstrap como dependencia

>

Para usar bootstrap como dependencia, dentro de la carpeta principal del proyecto, ejecuta el siguiente comando:

npm install bootstrap

Después de la ejecución deberá de verse una pantalla como la siguiente

Una web en node.js

Base de datos

bootstrap como dependencia

>

La estructura de la carpeta public debe de quedar de la siguiente forma:

public/
├── css/
│   └── bootstrap.min.css
├── js/
│   └── bootstrap.bundle.min.js
├── index.html
└── scripts.js

Una web en node.js

Base de datos

bootstrap como dependencia

>

Edita el index html de public

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CRUD con Node.js y Bootstrap</title>
  <!-- Bootstrap CSS desde node_modules -->
  <link href="/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  <div class="container mt-5">
    <h1 class="text-center">CRUD con Node.js y Bootstrap</h1>

    <!-- Formulario para crear registros -->
    <form id="form-crear" class="mt-4">
      <div class="mb-3">
        <label for="nombre" class="form-label">Nombre:</label>
        <input type="text" class="form-control" id="nombre" name="nombre" required>
      </div>
      <div class="mb-3">
        <label for="email" class="form-label">Email:</label>
        <input type="email" class="form-control" id="email" name="email" required>
      </div>
      <div class="mb-3">
        <label for="mensaje" class="form-label">Mensaje:</label>
        <textarea class="form-control" id="mensaje" name="mensaje" required></textarea>
      </div>
      <button type="submit" class="btn btn-primary">Crear</button>
    </form>

  <!-- Script para manejar el CRUD desde el frontend -->
  <script>
    // Función para cargar y mostrar los registros
    async function cargarRegistros() {
      const response = await fetch('/formularios');
      const registros = await response.json();
      const lista = document.getElementById('lista-registros');
      lista.innerHTML = registros.map(registro => `
        <li>
          ID: ${registro.id} | Nombre: ${registro.nombre} | Email: ${registro.email} | Mensaje: ${registro.mensaje}
          <button onclick="eliminarRegistro(${registro.id})">Eliminar</button>
          <button onclick="editarRegistro(${registro.id})">Editar</button>
        </li>
      `).join('');
    }

    // Función para crear un registro
    document.getElementById('form-crear').addEventListener('submit', async (e) => {
      e.preventDefault();
      const nombre = document.getElementById('nombre').value;
      const email = document.getElementById('email').value;
      const mensaje = document.getElementById('mensaje').value;

      await fetch('/formularios', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ nombre, email, mensaje })
      });

      cargarRegistros();
    });

    // Función para eliminar un registro
    async function eliminarRegistro(id) {
      await fetch(`/formularios/${id}`, { method: 'DELETE' });
      cargarRegistros();
    }

    // Función para editar un registro (puedes implementarla si lo necesitas)
    async function editarRegistro(id) {
      const nuevoNombre = prompt('Nuevo nombre:');
      const nuevoEmail = prompt('Nuevo email:');
      const nuevoMensaje = prompt('Nuevo mensaje:');

      await fetch(`/formularios/${id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ nombre: nuevoNombre, email: nuevoEmail, mensaje: nuevoMensaje })
      });

      cargarRegistros();
    }

    // Cargar registros al iniciar la página
    cargarRegistros();
  </script>


    <!-- Lista de registros -->
    <h2 class="mt-5">Registros Existentes</h2>
    <ul id="lista-registros" class="list-group"></ul>
  </div>

  <!-- Bootstrap JS desde node_modules -->
  <script src="/js/bootstrap.bundle.min.js"></script>

  <!-- Tu script personalizado -->
  <script src="scripts.js"></script>
</body>
</html>

Una web en node.js

Base de datos

bootstrap como cdn

>

agrega la siguiente linea entre las etiquetas head

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">

Y esta otra al final del fichero index.html

 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
Made with Slides.com