Blog Tinux Net

Web

All blog posts: web

  • Publicado en

    Para crear un CRUD (Crear, Leer, Actualizar y Eliminar) de usuarios utilizando Node.js con Express como backend y MariaDB como base de datos, siguiendo tu configuración con Apache2 y un dominio virtual hay que seguir estos pasos:

    Configuración inicial
    Primero, asegurarse de tener instalados Node.js, npm y MariaDB en el sistema. Luego, crea un nuevo proyecto e instalar las dependencias necesarias:

    mkdir crud-usuarios
    cd crud-usuarios
    npm init -y
    npm install express mysql2 body-parser
    

    Estructura del proyecto
    Crear la siguiente estructura de archivos:

    crud-usuarios/
    ├── app.js
    ├── config/
    │ └────── db.js
    └── routes/
    └────── users.js

    Configuración de la base de datos
    En el archivo config/db.js, configura la conexión a MariaDB:
    [ config/db.js ]

    const mysql = require('mysql2');
    
    const connection = mysql.createConnection({
      host: 'localhost',
      user: 'tu_usuario',
      password: 'tu_contraseña',
      database: 'tu_base_de_datos'
    });
    
    connection.connect(error => {
      if (error) throw error;
      console.log('Conexión exitosa a la base de datos.');
    });
    
    module.exports = connection;
    

    Configuración del servidor Express
    En el archivo app.js, configura el servidor Express:

    [ app.js ]

    const express = require('express');
    const bodyParser = require('body-parser');
    const usersRoutes = require('./routes/users');
    
    const app = express();
    
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));
    
    app.use('/api/users', usersRoutes);
    
    const PORT = process.env.PORT || 3000;
    app.listen(PORT, () => {
      console.log(`Servidor corriendo en el puerto ${PORT}`);
    });
    

    Implementación de las rutas CRUD
    En el archivo routes/users.js, implementa las rutas para el CRUD:
    [ routes/users.js ]

    const express = require('express');
    const router = express.Router();
    const db = require('../config/db');
    
    // Crear un usuario
    router.post('/', (req, res) => {
      const { user, username } = req.body;
      const query = 'INSERT INTO users (user, username) VALUES (?, ?)';
    
      db.query(query, [user, username], (error, results) => {
        if (error) {
          return res.status(500).json({ error: error.message });
        }
        res.status(201).json({ id: results.insertId, user, username });
      });
    });
    
    // Obtener todos los usuarios
    router.get('/', (req, res) => {
      const query = 'SELECT * FROM users';
    
      db.query(query, (error, results) => {
        if (error) {
          return res.status(500).json({ error: error.message });
        }
        res.json(results);
      });
    });
    
    // Obtener un usuario por ID
    router.get('/:id', (req, res) => {
      const query = 'SELECT * FROM users WHERE id = ?';
    
      db.query(query, [req.params.id], (error, results) => {
        if (error) {
          return res.status(500).json({ error: error.message });
        }
        if (results.length === 0) {
          return res.status(404).json({ message: 'Usuario no encontrado' });
        }
        res.json(results[0]);
      });
    });
    
    // Actualizar un usuario
    router.put('/:id', (req, res) => {
      const { user, username } = req.body;
      const query = 'UPDATE users SET user = ?, username = ? WHERE id = ?';
    
      db.query(query, [user, username, req.params.id], (error, results) => {
        if (error) {
          return res.status(500).json({ error: error.message });
        }
        if (results.affectedRows === 0) {
          return res.status(404).json({ message: 'Usuario no encontrado' });
        }
        res.json({ id: req.params.id, user, username });
      });
    });
    
    // Eliminar un usuario
    router.delete('/:id', (req, res) => {
      const query = 'DELETE FROM users WHERE id = ?';
    
      db.query(query, [req.params.id], (error, results) => {
        if (error) {
          return res.status(500).json({ error: error.message });
        }
        if (results.affectedRows === 0) {
          return res.status(404).json({ message: 'Usuario no encontrado' });
        }
        res.json({ message: 'Usuario eliminado correctamente' });
      });
    });
    
    module.exports = router;
    

    Configuración de Apache2 como proxy inverso
    Para que Apache2 funcione como proxy inverso para la aplicación Node.js, se necesita configurar un virtual host. Editar el archivo de configuración del dominio virtual:

    sudo nvim  /etc/apache2/sites-available/subdomain.dominio.net.conf
    

    Añadir la siguiente configuración:

    <VirtualHost *:80>
        ServerName subdomain.dominio.net
        ProxyPreserveHost On
        ProxyPass / http://localhost:3000/
        ProxyPassReverse / http://localhost:3000/
        ErrorLog ${APACHE_LOG_DIR}/subdomain.dominio.net-error.log
        CustomLog ${APACHE_LOG_DIR}/subdomain.dominio.net-access.log combined
    </VirtualHost>
    

    Habilitar el módulo proxy de Apache2 y reiniciar el servicio:

    sudo a2enmod proxy proxy_http
    sudo systemctl restart apache2
    

    Uso del CRUD
    Ahora puedes usar el CRUD a través de tu dominio virtual:

    • Crear un usuario: POST http://subdomain.dominio.net/api/users
    • Obtener todos los usuarios: GET http://subdomain.dominio.net/api/users
    • Obtener un usuario por ID: GET http://subdomain.dominio.net/api/users/:id
    • Actualizar un usuario: PUT http://subdomain.dominio.net/api/users/:id
    • Eliminar un usuario: DELETE http://subdomain.dominio.net/api/users/:id

    Iniciar la aplicación Node.js con:

    node app.js
    

    Este CRUD te permitirá gestionar los usuarios en tu base de datos MariaDB a través de una API RESTful, accesible desde tu dominio virtual http://subdomain.dominio.tinux.net

  • Publicado en

    Tabla de tamaños imagenes

    Tipo de Imagen Desktop Mobile Ratio
    Background 2560 x 1400 pixels 360 x 640 pixels 16:9
    Principal 1280 x 720 pixels 360 x 200 pixels 16:9
    Banner 1200 x 400 pixels 360 x 120 pixels 3:1
    Blog 1200 x 800 pixels 360 x 240 pixels 3:2
    Logo (rectangle) 400 x 100 pixels 160 x 40 pixels 4:1
    Logo (square) 100 x 100 pixels 60 x 60 pixels 1:1
    Favicon 16 x 16 pixels 16 x 16 pixels 1:1
    Íconos redes 32 x 32 pixels 48 x 48 pixels 1:1
    Lightbox (full screen) 1920 x 1080 pixels 360 x 640 pixels 16:9
    Thumbnail 300 x 300 pixels 90 x 90 pixels 1:1
  • Publicado en

    index.html

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <title>Simple AJAX - GET REQUEST</title>
      </head>
      <body>
    
        <button onclick="sendRequest()">
    

    Hace la llamada a la funcion javascript del archivo script.js

          Send Ajax Request
        </button>
    
        <div id="container"></div>
    <script src="script.js" type="text/javascript"></script>
      </body>
    </html>
    

    script.js:

    function sendRequest() {
    

    Creamos el Objeto que va a recibir los datos a través de AJAX

        var theObject = new XMLHttpRequest();
    

    Verificamos que se ha enviado una petición

        theObject.open('POST', 'backend.php', true);
    

    Indicamos que tipo de cabecera se ha enviado a través del navegador

        theObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    

    Vemos en cual es el State o Estado

        theObject.onreadystatechange = function() {
          if(theObject.readyState === 4 & theObject.status === 200) {
    

    Si el Estado es Ok =200 y Enviado procedemos a insertar en el div con id container el Texto del Objeto

            document.getElementById('container').innerHTML = theObject.responseText;
          }
        }
    

    Y lo enviamos

        theObject.send('username=Fazt&password=secret');
      }
    

    Y el fichero que se ejecutara en el Backend: backend.php:

    <?php
    
    if(isset($_POST)) {
      echo $_POST['username'];
      echo '<br>';
      echo $_POST['password'];
    }
    
      #echo 'Working!';
    
    ?>
    
  • Publicado en

    Autocompletado Input

    Un sencillo input para un formulario.

    input.html:

    La clase del div es para poner los colores del background , la posicion general del div y su tipo de letra,

    Los estilos style.css:

    body {
      background-color: blue;
      font-family: sans-serif;
    }
    
    .autocomplete {
      display: flex;
      flex-direction: column;
      min-height: 100vh;
      align-items: center;
      justify-content: top;
      padding-top: 100px;
    }
    
    input {
      font-size: 2em;
      width: 300px;
    }
    
    .autocomplete-results {
      display: none; // Se indica None, para que no se muestre, luego con el javascript lo habilitaremos
      width: 300px;
      margin-top: -2px;
      font-size: 1.3em;
      color: #eee;
      list-style: none;
      margin: 0;
      padding: 0;
    }
    
      .autocomplete-results li {
        margin: 0;
        padding: 0;
        padding: 10px 0 10px 10px;
        border-right: 2px solid #eee;
        border-bottom: 2px solid #eee;
        border-left: 2px solid #eee;
      }
    
      .autocomplete-results li:hover {
        background-color: #eee;
        color: blue;
        cursor: pointer;
      }
    

    Y ahora el javascript: script.js:

    let input = document.querySelector("input");
    let autocomplete_results = document.getElementById('autocomplete-results');
    
    input.addEventListener('keyup',  (event) =>  {
      autocomplete_results.style.display = 'block';
      let key = event.target.value;
    
      console.log(key)
    
      if(key.length > 0) {
        search(key);
      }
      else {
        build_list();
      }
    })
    
    const search = (key) => {
      fetch(`https://restcountries.eu/rest/v2/name/${key}?fields=name`)
      .then(res => res.json())
      .then(data => {
        if(Array.isArray(data)) {
          build_list(data.map(item => {
            return item.name
          }))
        }
      })
    }
    
    const build_list = (items) => {
      console.log('elems', items)
    
      if(items === undefined) {
        items = [];
      }
    
      autocomplete_results.innerHTML = '';
    
      items.slice(0,10).map(item =>  {
        autocomplete_results.innerHTML += `<li>${item}</li>`;
                          })
    }
    
    document
      .getElementById("autocomplete-results")
      .addEventListener("click", e => {
        if (e.target && e.target.nodeName == "LI") {
    
          input.value = e.target.innerHTML;
          build_list()
        }
      });
    
  • Publicado en

    Instalacion

    npm create vite@latest
    

    Pero tambien se puede crear el proyecto directamente con

    # npm 7+, extra double-dash is needed:
    npm create vite@latest vite-project -- --template react
    

    Crea el Directorio vite-project Luego :

    cd vite-project
    npm install
    npm run dev
    

    Nos lanzara un script y el puerto abierto para el renderizado. VITE v5.3.3 ready in 180 ms

    ➜ Local: http://localhost:5173/
    ➜ Network: use --host to expose
    ➜ press h + enter to show help

    press r + enter to restart the server
    press u + enter to show server url
    press o + enter to open in browser
    press c + enter to clear console
    press q + enter to quit