— Alfredo de Jesús Gutiérrez Gómez, Dr
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?
Unidad 1.
Comunicación Segura
Unidad 2.
Framework para web empresarial
Unidad 3.
Desarrollo MVC (modelo, vista, controlador).
El incumplimiento de las tareas en tiempo y forma llevarán a una no aprobación del curso.
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.
Unidad 1
Unidad 2
Unidad 3
Actividades de encuadre
En una hoja escribe la respuesta a la siguiente pregunta:
Una vez contestadas las preguntas pulsa aquí para agregarte al grupo y sube tus respuesta.
Se enumeran las recomendaciones que se deben seguir para la realización de las actividades
Trabajos:
Párrafos:
Ortografía:
Referencia bibliográfica:
Lista de referencias bibliográfica
Introducción y conclusión
Formato del trabajo:
Tablas:
Imágenes / diagramas / gráficas:
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.
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.
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
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
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.
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.
Manejo de Sesiones
Manejo de Sesiones
Actividad de aprendizaje
Pulsa aquí para resolver la actividad o scanea el qr
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.
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
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.
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.
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.
Seguridad en la Transmisión
Actividad de aprendizaje
Pulsa aquí o escanea el qr
the code
Para establecer una comunicación segura entre un cliente y un servidor, se utiliza el protocolo HTTPS, que cifra los datos transmitidos.
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');
});
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.key.pem
) restringiendo los permisos del sistema de archivos.the code
Ejecutando el código:
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
.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
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
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)
¿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)
Openssl en win2
Openssl en linux
Para distribuciones derivadas de debian (*.deb)
Para distribuciones derivadas de Redhat (*.rpm)
Openssl en MacOsX
Ejecuta el comando: brew install openssl
Actividad de Aprendizaje
Pulsa aquí o escanea el qr
El ambiente
$ mkdir webnode
$ cd webnode
$ npm init -y
las dependencias (framework)
$ npm install express
El servidor web
// 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}/`);
});
ejecutando el server
$ node servidor.js
las rutas
¿Rutas?
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.
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.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");
});
las rutas
Rutas -> ejemplos
http://localhost:3000/usuarios
→ Devuelve una lista de usuarios.http://localhost:3000/usuarios/5
→ Devuelve el usuario con ID 5
.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");
});
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");
});
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
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
La estructura
proyectoWeb/
├── public/
│ ├── index.html
│ ├── about.html
│ └── styles.css
├── server.js
└── package.json
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
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
Actividad de aprendizaje
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.
Formularios
El proyecto
mkdir formulario-nodejs
cd formulario-nodejs
npm init -y
>
Formularios
Las dependencias
npm install express ejs
>
Instala Express y EJS
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
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
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
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:
Formularios
La ejecución
node app.js
>
Iniciar el servidor: En la terminal, ejecuta el siguiente comando para iniciar el servidor
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
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.
Base de datos
Configuración
>
mkdir mi-proyecto-mysql
cd mi-proyecto-mysql
Crea una carpeta para el proyecto
Base de datos
Configuración
>
npm init -y
Inicializa el proyecto
Base de datos
Configuración
>
npm install express mysql2
Instala las librerías y dependencias
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:
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
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
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
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.
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.
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.
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.
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á.
Base de datos
La ejecución
>
npm run dev
Si se instalo nodemon
De lo contrario
npm start
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
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"
},
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"
}
}
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
Base de datos
La revisión
>
Ahora se corrobora que se haya guardado los datos en mysql
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
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;
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');
});
};
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}`);
});
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>
Base de datos
El CRuD
>
Se ejecuta con el comando:
npm run dev
Se deberá mostrar algo como esto en la terminal
Base de datos
El CRuD
>
En el navegador algo como esto
Base de datos
bootstrap
>
Para agregar bootstrap al proyecto se puede hacer de diferentes maneras, como:
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
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
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>
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>