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
- Manejo de sesiones
- Seguridad en las transacciones
Temas del curso
Unidad 2.
Framework para web empresarial
- Frameworks de desarrollo.
- Instalación del Framework.
- Configuración de las aplicaciones
Temas del curso
Unidad 3.
Desarrollo MVC (modelo, vista, controlador).
- Modelo
- Vista
- 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:
- ¿Qué esperas que se enseñe en este curso?
- ¿A qué te comprometes en este curso?
- ¿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
ycert.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
- No expongas los certificados en repositorios públicos.
-
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 archivokey.pem
. -
-out cert.pem
: Guarda el certificado en el archivocert.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 ruta de instalación, suele ser algo como: c:/ProgramFile/OpenSSL-Win64/bin.
- 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).
- abre una terminal (cmd o powershel) y ejecuta
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 ID5
.
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>
Aplicación Web para I.4.0
By Alfredo de Jesús Gutiérrez Gómez
Aplicación Web para I.4.0
Presentación donde se desarrolla la materia de aplicación web para I.4.0
- 285