Práctica 2: Tienda mejorada - Sianats/LTAW-Practicas GitHub Wiki
Práctica 2: Interacción cliente-servidor. Tienda mejorada
Índice
Introducción
El objetivo de esta práctica es ampliar la tienda on-line de la práctica 1 para incluir las nuevas características que se indican en los siguientes apartados.
Base de datos en fichero JSON
La tienda deberá tener una base de datos implementada en el fichero tienda.json. Debe contener los siguientes datos:
-
Usuarios: Todos los usuarios registrados en la tienda. Debe haber al menos dos: el usuario root y un usuario normal. Cada usuario tiene un nombre (el que se usa para el login), un nombre real y una dirección de correo
-
Productos: Todos los productos disponibles en la tienda. Para cada producto, al menos se deberá tener la siguiente información: nombre, descripción, precio y cantidad en stock
-
Pedidos: Registro de los pedidos realizados. Cada pedido contiene la siguiente información: nombre de usuario, dirección de envío, numero de la tarjeta y una lista con los nombres de los productos comprados (Supondremos que la cantidad es siempre 1 para simplificar)
Documentación técnica:
Mi código de esta práctica se encuentra en mi Repositorio 2.
Front-end
Tanto en los css como en el html, hay especificaciones de qué hace cada cosa. Por lo que solo me queda enseñar el resultado estético.
Al iniciar el servidor en tu web aparece la siguiente página:
En ella, puedes pulsar el icono de usuario para iniciar sesión:
Una vez con la sesión iniciada, aparecerá tu nombre de usuario (donde antes estaba el icono):
Con la sesión ya iniciada, ahora puedes añadir productos al carrito. Una vez añadidos, deberían aparecerte las cookies con el nombre de cada producto añadido al carro:
Después, accede al icono del carro para formalizar tu compra:
Una vez finalizada la compra y si todo ha ido bien, te aparecerá este mensaje de despedida, con un resumen de tus productos adquiridos:
Back-end
Adjunto mi código, con sus funciones explicadas una a una en los comentarios del propio:
- Código de mi fichero tienda.js:
const http = require('http');
const fs = require('fs');
const PUERTO = 9090;
const PRODUCTOS_JSON = fs.readFileSync('productos.json');
//-- Obtener el array de productos
let productos = JSON.parse(PRODUCTOS_JSON);
// Se crea el servidor
const server = http.createServer((req, res) => {
let myURL = new URL (req.url, 'http://' + req.headers['host']);
let page = "";
let succesful = false;
let cookie1 = "Carrito=";
let nombre = "";
let carro = [];
//-- Leer la Cookie recibida
const cookie = req.headers.cookie;
//-- Hay cookie
if (cookie) {
//-- Obtener un array con todos los pares nombre-valor
let pares = cookie.split(";");
//-- Recorrer todos los pares nombre-valor
pares.forEach((element, index) => {
//-- Obtener los nombres y valores por separado
let [ok, valor] = element.split('=');
//-- Leer el usuario
//-- Solo si el nombre es 'User'
if (ok.trim() === 'User') {
nombre = valor;
} else if(ok.trim() === 'Carrito') {
cookie1 = element;
carro = valor.split('-');
carro.pop();
}
});
}
//Se llama a la página principal por defecto
if(myURL.pathname == '/procesar'){
nombre= myURL.searchParams.get('nombre');
if( nombre == productos["Usuario"][0]["User"] || nombre == productos["Usuario"][1]["User"]){
res.setHeader('Set-Cookie', 'User=' + nombre);
page = "calor.html";
succesful = true;
}
}else if(myURL.pathname == '/poner-freidora'){
if(nombre){
cookie1 += "Freidora-";
res.setHeader('Set-Cookie',cookie1);
page = "calor.html";
}
}else if(myURL.pathname == '/poner-frytop'){
if(nombre){
cookie1 += "Frytop-";
res.setHeader('Set-Cookie',cookie1);
page = "calor.html";
}
}else if(myURL.pathname == '/poner-conveccion'){
if(nombre){
cookie1 += "Conveccion-";
res.setHeader('Set-Cookie',cookie1);
page = "calor.html";
}
}else if(myURL.pathname == '/poner-pizza'){
if(nombre){
cookie1 += "Pizza-";
res.setHeader('Set-Cookie',cookie1);
page = "calor.html";
}
}else if(myURL.pathname == '/poner-mixto'){
if(nombre){
cookie1 += "Mixto-";
res.setHeader('Set-Cookie',cookie1);
page = "calor.html";
}
}else if(myURL.pathname == '/poner-cuecepasta'){
if(nombre){
cookie1 += "Cuecepasta-";
res.setHeader('Set-Cookie',cookie1);
page = "calor.html";
}
}else if(myURL.pathname == '/comprar'){
if(nombre){
const FICHERO_JSON_OUT = "productos.json";
direc = myURL.searchParams.get('direccion');
card = myURL.searchParams.get('tarjeta');
// productos["Pedidos"]["User"] = nombre;
// productos["Pedidos"]["Direccion"] = direc;
// productos["Pedidos"]["Card"] = card;
// productos["Pedidos"]["Producto"] = cookie1;
var pf = {"User": nombre, "Direccion": direc, "Card": card, "Producto": cookie1};
productos["Pedidos"].push(pf);
//-- Convertir la variable a cadena JSON
let myJSON = JSON.stringify(productos);
//-- Guardarla en el fichero destino
fs.writeFileSync(FICHERO_JSON_OUT, myJSON);
page = "comprado.html";
}
}
else if(myURL.pathname == '/'){
page = 'calor.html';
} else {
page = myURL.pathname.slice(1);
}
fs.readFile(page, function(err, data) {
if (err) {
// Si se pide un recurso que no existe, salta la página de error
res.writeHead(404, {'Content-Type': 'text/html'});
return fs.createReadStream('error.html').pipe(res)
}
if(page.includes('.html')){
res.setHeader('Content-Type', 'text/html');
} else if(page.includes('.css')){
res.setHeader('Content-Type', 'text/css');
} else if(page.includes('.js')){
res.setHeader('Content-Type', 'application/js');
} else if(page.includes('.json')){
res.setHeader('Content-Type', 'application/json');
} else if(page.includes('.jpg')){
res.setHeader('Content-Type', 'image/jpg');
} else if(page.includes('.png')){
res.setHeader('Content-Type', 'image/png');
} else if(page.includes('.gif')){
res.setHeader('Content-Type', 'image/gif');
}
if (succesful == true){
data = data.toString().replace('<a href="login.html"><img src="fotos/usuario.png" alt="" width="30px" ;=""></a>', nombre);
}
if(page == 'carrito.html' || page == 'comprado.html'){
let resumen = '';
carro.forEach((p) => {
resumen += p + '<br>';
})
resumen += '';
data = data.toString().replace('Aún no hay nada añadido al carrito :(', resumen);
}
res.write(data);
res.end();
});
});
server.listen(PUERTO);
console.log("Escuchando en puerto: " + PUERTO);
Manual de usuario
Al igual que en la práctica 1, deberás tener instalado Node.js para poder usar e iniciar mi web.
Al descargarte mi repositorio, accede a la carpeta P2 y abre su terminal. Escribe el comando node tienda.js
y, después, accede a tu navegador e introduce la URL localhost:9090
.
Desde mi página principal puedes ver toda la tienda, pero no comprar(si intentas añadir algo al carro sin iniciar sesión, te redigirá a la página de error). Para poder hacerlo, debes pulsar el icono de usuario e iniciar sesión. ¡Tranquil@! no necesitas registrarte, solo deberás introducir uno de los siguientes usuarios que ya están establecidos en mi servidor:
- Root
- Pep89
Asegúrate de escribirlos tal cual (mayúsculas incluidas), o no reconocerá el usuario y te redigirá a la página de error (si todo va correctamente deberías volver a la página principal). ¡Después de iniciar sesión ya podrás comprar mis productos!. Añade todos los que quieras al carro y, cuando lo tengas todo, accede al icono del carro de la compra. Ahí te pedirá formalizar tu compra por los items con tu tarjeta de crédito y tu dirección. Una vez hecho el pago, te enseñará un resumen de tu compra y ¡Listo!, ya has comprado en mi tienda.