Formularios y Multer en Node.js

Choose a study mode

Play Quiz
Study Flashcards
Spaced Repetition
Chat to Lesson

Podcast

Play an AI-generated podcast conversation about this lesson
Download our mobile app to listen on the go
Get App

Questions and Answers

¿Cuál es el tipo de formulario necesario para permitir la subida de ficheros?

  • text/html
  • multipart/form-data (correct)
  • application/x-www-form-urlencoded
  • application/json

¿Qué función cumple la librería multer en Node.js al procesar formularios con subida de archivos?

  • Define la estructura de la base de datos.
  • Valida los datos del formulario.
  • Gestiona las rutas del servidor.
  • Procesa y almacena los archivos subidos. (correct)

En la configuración de multer, ¿qué define el elemento storage?

  • La encriptación de los archivos subidos.
  • El tipo de archivo aceptado (ej., jpg, png).
  • El tamaño máximo de los archivos permitidos.
  • La ubicación donde se guardarán los archivos y el nombre que se les asignará. (correct)

En el código proporcionado, ¿cuál es la función de Date.now() al nombrar los archivos subidos?

<p>Asegurar que el nombre del archivo sea único, evitando sobreescrituras. (A)</p> Signup and view all the answers

Si se quiere acceder al nombre del archivo subido en el servicio POST, ¿a través de qué objeto y propiedad se puede obtener?

<p><code>req.file.filename</code> (A)</p> Signup and view all the answers

¿Cuál es el propósito del middleware upload.single('imagen') en la ruta POST mostrada?

<p>Subir un único archivo desde un campo llamado 'imagen'. (B)</p> Signup and view all the answers

¿Qué problema busca solucionar el middleware method-override en relación con los formularios HTML?

<p>Permitir usar métodos HTTP como PUT o DELETE en formularios que solo soportan POST. (D)</p> Signup and view all the answers

Si no se utiliza Date.now() al configurar el nombre del archivo en multer, ¿qué podría ocurrir?

<p>Podrían sobreescribirse archivos existentes con el mismo nombre. (A)</p> Signup and view all the answers

¿Cuál es el propósito principal de agregar formularios a una aplicación Node.js, según el contenido?

<p>Permitir la interacción del usuario con la base de datos para insertar, borrar o modificar contenido. (B)</p> Signup and view all the answers

En el contexto de la aplicación ContactosWeb_v2, ¿qué acción se realiza primero para implementar la funcionalidad de inserción de contactos?

<p>Crear una vista llamada <code>contactos_nuevo.njk</code> que contiene el formulario de inserción. (C)</p> Signup and view all the answers

¿Qué bloque de código en la vista contactos_nuevo.njk define el contenido principal del formulario?

<p>{% block contenido %} ... {% endblock %} (A)</p> Signup and view all the answers

¿Cuál es la función del enlace 'Nuevo contacto' en el menú de navegación de la aplicación?

<p>Enviar al usuario a la ruta <code>/contactos/nuevo</code> para mostrar el formulario de inserción. (B)</p> Signup and view all the answers

Según el contenido, ¿en qué archivo se define la ruta para mostrar el formulario de inserción de contactos?

<p>En el archivo <code>routes/contactos.js</code>. (C)</p> Signup and view all the answers

En el enrutador de contactos (routes/contactos.js), ¿qué método HTTP se utiliza para manejar la petición que muestra el formulario de inserción?

<p>GET (C)</p> Signup and view all the answers

¿Qué problema puede surgir si la ruta /contactos/nuevo se define DESPUÉS de la ruta /contactos/:id en el enrutador de contactos y cómo se puede solucionar?

<p>La ruta <code>/contactos/nuevo</code> nunca se ejecutará porque <code>/contactos/:id</code> capturará todas las peticiones; ubicar la ruta <code>/contactos/nuevo</code> ANTES o renombrarla a <code>/contactos/nuevo/contacto</code>. (B)</p> Signup and view all the answers

¿A qué ruta se envían los datos del formulario cuando el usuario hace clic en 'Enviar'?

<p>/contactos (C)</p> Signup and view all the answers

En el contexto del código proporcionado, ¿cuál es la función principal de Object.keys(error.errors)?

<p>Obtener un array con los nombres de los campos del modelo que no superaron la validación. (D)</p> Signup and view all the answers

Si la validación del campo 'nombre' falla porque tiene menos de tres caracteres, y Nunjucks tiene habilitado el auto-escape, ¿cómo se mostraría el mensaje de error en la vista?

<p>El mensaje se mostraría literalmente, incluyendo las etiquetas HTML como texto. (B)</p> Signup and view all the answers

¿Cuál es el propósito de la cláusula .catch en el código Node.js proporcionado?

<p>Capturar y procesar errores que ocurren durante la operación de guardado del contacto. (A)</p> Signup and view all the answers

En el contexto del código proporcionado, ¿qué significa res.redirect(req.baseUrl)?

<p>Redirigir a la ruta base de la API actual después de guardar un nuevo contacto exitosamente. (D)</p> Signup and view all the answers

¿Qué ocurriría si no se utiliza el modificador safe en Nunjucks al mostrar un mensaje de error que contiene etiquetas HTML?

<p>Las etiquetas HTML se interpretarían y podrían causar problemas de seguridad XSS. (A)</p> Signup and view all the answers

¿Cuál es la función del método save() en el contexto del código proporcionado?

<p>Guardar los datos del nuevo contacto en la base de datos. (B)</p> Signup and view all the answers

¿Qué tipo de datos se espera que contenga req.body.telefono basándose en el código?

<p>Una cadena de texto representando el número de teléfono del contacto. (A)</p> Signup and view all the answers

¿Por qué es importante recorrer los errores producidos en el campo errors del error devuelto en la cláusula catch?

<p>Para mostrar al usuario información específica sobre los errores de validación que ocurrieron. (A)</p> Signup and view all the answers

¿Cuál de las siguientes opciones describe mejor el propósito principal de la librería validator.js?

<p>Validar y sanear cadenas de texto en aplicaciones Node.js. (A)</p> Signup and view all the answers

En el contexto de la validación de datos con validator.js, ¿qué significa 'sanear' una cadena de texto?

<p>Limpiar la cadena, eliminando espacios innecesarios o escapando caracteres especiales. (D)</p> Signup and view all the answers

Antes de usar validator.js en un proyecto Node.js, ¿cuál es el primer paso necesario?

<p>Instalar la librería utilizando el comando <code>npm install validator</code>. (B)</p> Signup and view all the answers

¿Qué función de validator.js se utilizaría para verificar si una cadena de texto tiene una longitud mínima de 5 caracteres?

<p><code>validator.isLength(cadena, {min: 5})</code> (B)</p> Signup and view all the answers

En el ejemplo de código proporcionado, ¿qué ocurre si la validación del nombre falla (está vacío o tiene menos de 3 caracteres)?

<p>Se redirige a una página de error específica para el nombre. (C)</p> Signup and view all the answers

¿Cuál es la principal diferencia entre usar validator.js directamente y utilizar los mecanismos de validación de Mongoose?

<p><code>validator.js</code> valida datos antes de interactuar con la base de datos, mientras que Mongoose valida los datos al nivel del esquema de la base de datos. (B)</p> Signup and view all the answers

¿Qué tipo de datos se espera que maneje principalmente la librería validator.js según el contexto proporcionado?

<p>Cadenas de texto recibidas en peticiones HTTP. (B)</p> Signup and view all the answers

En el código de ejemplo, ¿qué validación se aplica al número de teléfono además de verificar que sea un valor numérico?

<p>Se valida que el número de teléfono tenga exactamente 9 caracteres. (D)</p> Signup and view all the answers

¿Cuál de las siguientes opciones describe correctamente el propósito de configurar express como urlencoded al recibir datos de un formulario en una aplicación Node.js?

<p>Analiza los datos codificados en la URL del formulario, haciéndolos accesibles en el objeto <code>req.body</code>. (C)</p> Signup and view all the answers

¿Por qué es necesario instalar y configurar la librería method-override en una aplicación Node.js al implementar la funcionalidad de borrado de libros?

<p>Porque permite simular peticiones HTTP DELETE en navegadores que no las soportan nativamente. (B)</p> Signup and view all the answers

En el contexto de la edición de libros en una aplicación Node.js, ¿cuál es el propósito principal de utilizar el método HTTP PUT en la ruta de modificación?

<p>Informar al servidor que debe reemplazar completamente el libro existente con los nuevos datos. (C)</p> Signup and view all the answers

Después de dar de alta un nuevo libro en la base de datos, ¿cuál es la práctica recomendada en la ruta POST para /libros?

<p>Redirigir al usuario al listado de libros. (C)</p> Signup and view all the answers

Si la operación de eliminar un libro falla en la ruta DELETE para /libros, ¿qué acción se recomienda tomar?

<p>Mostrar una página de error específica al usuario. (B)</p> Signup and view all the answers

En el contexto de la aplicación de libros, ¿qué vista se encarga de presentar el formulario para agregar un nuevo libro?

<p><code>libros_nuevo.njk</code> (A)</p> Signup and view all the answers

¿Cómo se acceden a los datos enviados desde un formulario cuando se realiza una petición POST en Express.js?

<p>A través del objeto <code>req.body</code>. (C)</p> Signup and view all the answers

En una aplicación Node.js con Express, ¿qué paso es fundamental para asegurar que los datos del formulario enviados con urlencoded puedan ser procesados correctamente?

<p>Configurar el middleware <code>express.urlencoded({ extended: true })</code>. (B)</p> Signup and view all the answers

¿Cuál es la principal limitación que motiva el uso de method-override al trabajar con formularios HTML y métodos HTTP como DELETE?

<p>Los formularios HTML nativamente no soportan los métodos HTTP DELETE o PUT, solo GET y POST. (A)</p> Signup and view all the answers

Después de instalar el módulo method-override, ¿en qué parte del código de la aplicación Node.js es crucial configurarlo y por qué?

<p>Debe configurarse antes de cargar los enrutadores pero después del middleware de express, para que pueda interceptar y modificar las peticiones antes de que lleguen a las rutas. (B)</p> Signup and view all the answers

En el contexto del código proporcionado, ¿cuál es el propósito del campo oculto _method en el formulario?

<p>Especifica el método HTTP real (ej., DELETE, PUT) que se debe utilizar para la petición, en lugar del método POST predeterminado del formulario. (A)</p> Signup and view all the answers

Considerando el snippet de código del formulario en contactos_listado.njk, ¿qué atributo del formulario es crucial para que method-override funcione correctamente y por qué?

<p>El atributo <code>action</code> debe apuntar a una URL que coincida con la ruta DELETE definida en el servidor para el borrado del contacto. (D)</p> Signup and view all the answers

En el código del middleware de methodOverride, ¿cuál es la finalidad de la línea delete req.body._method;?

<p>Evita que el valor del campo <code>_method</code> se utilice accidentalmente en la lógica de la aplicación después de ser procesado por <code>methodOverride</code>. (C)</p> Signup and view all the answers

¿Qué ocurriría si el middleware methodOverride se configurara después de la definición de las rutas en el archivo index.js?

<p>El middleware interceptaría las peticiones después de que ya hayan sido procesadas por las rutas, haciendo que no tenga ningún efecto. (C)</p> Signup and view all the answers

¿Cuál es la ventaja principal de usar method-override en lugar de implementar la lógica DELETE directamente con JavaScript y AJAX en el cliente?

<p><code>method-override</code> simplifica la implementación al evitar la necesidad de escribir código JavaScript y gestionar peticiones asíncronas en el cliente. (B)</p> Signup and view all the answers

Si en lugar de un formulario, se utilizara una petición AJAX para enviar la solicitud de borrado, ¿sería necesario el uso de method-override en el servidor? ¿Por qué?

<p>No, porque las peticiones AJAX pueden enviar directamente métodos HTTP como DELETE sin necesidad de simulación. (C)</p> Signup and view all the answers

Flashcards

¿Qué es method-override?

Módulo de NPM que permite emparejar formularios del cliente con métodos del servidor.

¿Cómo instalar method-override?

Instala el módulo method-override en tu proyecto Node.js usando npm.

¿Cómo configurar method-override?

Configurar method-override para que reconozca el campo _method en los formularios.

¿Cómo redefinir el método DELETE en un formulario?

Añadir un campo oculto llamado _method al formulario con el valor 'DELETE'.

Signup and view all the flashcards

¿Qué es un campo 'hidden'?

Un campo en un formulario que no es visible para el usuario.

Signup and view all the flashcards

¿Cómo implementar el borrado en la vista de contactos?

Se utiliza un formulario para cada contacto con un botón de borrado asociado.

Signup and view all the flashcards

¿Qué es la ruta de borrado?

Definir la ruta en el servidor que responde a la petición de borrado (DELETE).

Signup and view all the flashcards

¿Cómo debe configurarse la ruta de borrado?

La ruta debe estar configurada para escuchar las peticiones DELETE.

Signup and view all the flashcards

Formularios en Node.js

Permiten insertar, borrar o modificar contenido en la base de datos a través de la aplicación web.

Signup and view all the flashcards

Vista 'contactos_nuevo.njk'

Una vista en Nunjucks que contiene la estructura del formulario HTML para la creación de un nuevo contacto.

Signup and view all the flashcards

Bloque 'contenido'

Bloque dentro de una plantilla base que define el contenido específico de la página, en este caso, el formulario de nuevo contacto.

Signup and view all the flashcards

Enlace 'Nuevo contacto'

Enlace en el menú de navegación que dirige al usuario al formulario para crear un nuevo contacto.

Signup and view all the flashcards

Ruta GET '/contactos/nuevo'

Ruta en el enrutador que se encarga de mostrar el formulario de creación de contactos.

Signup and view all the flashcards

Función de renderizado

Función que se ejecuta cuando se accede a la ruta '/contactos/nuevo', mostrando el formulario.

Signup and view all the flashcards

Orden de las rutas

El orden de las rutas es importante para evitar conflictos. La ruta más específica debe ir primero.

Signup and view all the flashcards

Ruta POST '/contactos'

Ruta a la que se envían los datos del formulario mediante el método POST para crear un nuevo contacto.

Signup and view all the flashcards

Ruta GET para '/libros/nuevo'

Define una ruta para mostrar el formulario de creación de libros.

Signup and view all the flashcards

Ruta POST para '/libros'

Maneja la creación de un nuevo libro con los datos enviados.

Signup and view all the flashcards

method-override

Librería para usar otros verbos HTTP como DELETE.

Signup and view all the flashcards

Middleware method-override

Middleware que busca un campo '_method' en el cuerpo de la petición.

Signup and view all the flashcards

Formulario de borrado

Formulario que envía una petición DELETE para borrar un libro.

Signup and view all the flashcards

Ruta DELETE para '/libros'

Ruta que elimina un libro basado en su ID y redirige al listado.

Signup and view all the flashcards

Enlace de edición de libro

Enlace/Botón que abre el formulario para editar un libro, con los campos ya rellenos.

Signup and view all the flashcards

Ruta PUT para modificar libros

Ruta que actualiza los datos de un libro y redirige al listado.

Signup and view all the flashcards

multipart/form-data

El tipo de formulario necesario para subir ficheros.

Signup and view all the flashcards

multer

Librería de Node.js para gestionar la subida de archivos.

Signup and view all the flashcards

destination

Función en multer que define dónde se guardan los archivos subidos.

Signup and view all the flashcards

filename

Función en multer que define el nombre del archivo subido.

Signup and view all the flashcards

originalname

Nombre original del archivo en el ordenador del cliente.

Signup and view all the flashcards

Date.now()

Función de JavaScript que devuelve la fecha y hora actual en milisegundos.

Signup and view all the flashcards

upload.single('nombre_campo')

Middleware de Multer que se aplica a un servicio para gestionar la subida de un único archivo.

Signup and view all the flashcards

¿Qué es la validación de datos?

Validación de datos en el lado del servidor.

Signup and view all the flashcards

¿Qué es validator.js?

Librería de JavaScript para validar y limpiar strings.

Signup and view all the flashcards

¿Qué permite hacer validator.js?

Comprobar la validez y limpiar cadenas de texto para asegurar un contenido adecuado.

Signup and view all the flashcards

¿Qué entendemos por 'sanear'?

Eliminar espacios al inicio o al final (trim), escapar caracteres, etc.

Signup and view all the flashcards

¿Qué tipo de dato son las peticiones?

Los datos que recibimos en una petición son textos hasta que se almacenan en la base de datos.

Signup and view all the flashcards

¿Cómo instalar validator.js?

Con el comando npm install validator.

Signup and view all the flashcards

¿Qué hace validator.isEmpty()?

Para comprobar si una cadena está vacía.

Signup and view all the flashcards

¿Qué hace validator.isLength()?

Para comprobar si la longitud de una cadena está dentro de un rango específico.

Signup and view all the flashcards

error.errors

Objeto que contiene detalles sobre errores de validación en Mongoose.

Signup and view all the flashcards

Object.keys(error.errors)

Devuelve un array con los nombres de los campos que fallaron la validación.

Signup and view all the flashcards

Mensaje de error genérico

Mensaje que se muestra si no se detectan errores específicos de validación.

Signup and view all the flashcards

Modificador 'safe' en Nunjucks

Evita que Nunjucks escape caracteres HTML, permitiendo mostrar HTML sin modificaciones.

Signup and view all the flashcards

nuevoContacto.save() en Mongoose

Método de Mongoose para guardar un nuevo documento en la base de datos.

Signup and view all the flashcards

res.redirect(req.baseUrl)

Redirige al usuario a la ruta base después de completar una acción.

Signup and view all the flashcards

Cláusula .catch()

Captura y maneja errores que ocurren durante la ejecución de una promesa.

Signup and view all the flashcards

res.render('error', {error: mensaje})

Renderiza una vista específica y le pasa datos para mostrar un mensaje de error.

Signup and view all the flashcards

Study Notes

Gestión de Formularios

  • Se añadirán formularios que permitirán insertar, borrar o modificar contenido de la base de datos.
  • Se modificarán las rutas para mostrar los formularios y recoger las peticiones de inserción, borrado y modificación.
  • Se continuará el proyecto ContactosWeb, copiándolo y renombrándolo a ContactosWeb_v2.

Formulario de inserción

  • Se creará una vista llamada contactos_nuevo.njk en la carpeta de views.
  • Esta vista heredará de base.njk y definirá el formulario en su bloque de contenido.
  • La vista contiene un formulario con campos para nombre, edad y teléfono, y un botón para enviar la información.
  • Para mostrar esta vista, se necesita un enlace "Nuevo contacto" en el menú de navegación de la aplicación (vista menu.njk), que enviará a la ruta /contactos/nuevo.
  • Para que la interfaz envie datos al servidor, es necesario definir una ruta en routes/contactos.js que atenderá las peticiones GET a /contactos/nuevo y renderizará la vista anterior.
  • La nueva ruta deberá ubicarse ANTES de la ruta de ficha del contacto.
  • Los datos del formulario se enviarán por POST a la ruta /contactos.
  • Se debe definir o redefinir esta ruta para que recoja los datos de la petición, realice la inserción y, por ejemplo, renderice el listado de contactos para comprobar que el nuevo contacto se ha añadido y, en caso de error, renderizar una vista de error.
  • Se utilizará el middleware incorporado en Express para procesar la petición cuando los datos lleguen desde un formulario normal.
  • Además de habilitar el procesado JSON app.use(express.json());, se habilitará el procesado urlencoded: app.use(express.urlencoded({ extended: true }));
    • El parámetro extended indica si se permite procesar datos que proporcionen información compleja (true) o solo se procesará información simple (false).

Formulario de borrado

  • En el listado de contactos, se añadirá un formulario con un botón de "Borrar" asociado a cada contacto y este botón se enviará a la URL /contactos.
  • Se debe añadir un mecanismo para que el formulario llegue a la ruta correcta en el servidor, ya que los formularios no aceptan el método DELETE.
  • Se instalará el módulo method-override de NPM, que permite emparejar formularios del cliente con métodos del servidor.
  • Se configura el parametro para que, si llega en el formulario un campo llamado method, utilice ese método en lugar al método del propio formulario.
  • Se incluye el módulo en el servidor principal index.js.
const methodOverride = require('method-override');
  • Luego, se añade el middleware.
app.use(methodOverride(function (req, res) {
  if (req.body && typeof req.body === 'object' && '_method' in req.body) {
    let method = req.body._method;
    delete req.body._method;
    return method;
  }
}))
  • En la vista de contactos_listado.njk, se define un pequeño formulario junto a cada contacto, con un botón para borrarlo a partir de su id.
  • En dicho formulario, se incluye un campo oculto cuyo nombre sea _method, indicando que la operación a realizar en el servidor es DELETE.
  • Se redefine la ruta para el borrado.
  • Se elimina el contacto cuyo ID llega en la URL y se redirige al listado de contactos, o se muestra la vista de error si no.

Formulario de Actualización

  • Para hacer una actualización, se deben combinar pasos de la inserción y el borrado.
  • Definir el formulario de actualización, pasando el objeto a modificar como parámetro a la vista para rellenar los campos.
  • Añadir una nueva ruta GET en el enrutador, por ejemplo, /contactos/editar, para renderizar el formulario.
  • El formulario se envía por PUT a la ruta correspondiente del enrutador, utilizando el campo oculto method para indicar que se quiere hacer PUT.
  • En la ruta put del enrutador, se recogen los datos del formulario, se realiza la actualización y se redirige a la vista de listado general o página de error.

Formulario y Ruta de Edición

  • Siguiendo los pasos anteriores, se define el formulario de edición en un archivo contactos_editar.njk.

  • Se añade una nueva ruta en el controlador para renderizar el formulario:

router.get('/editar/:id', (req, res) => {
  Contacto.findById(req.params['id']).then(resultado => {
    if (resultado) {
      res.render('contactos_editar', {contacto: resultado});
    } else {
      res.render('error', {error: "Contacto no encontrado"});
    }
  }).catch(error => {
    res.render('error', {error: "Contacto no encontrado"});
  });
});

Actualización de datos del contacto

  • La ruta put recoge los datos de la petición y actualiza el contacto:
router.put('/:id', (req, res) => {
  Contacto.findByIdAndUpdate(req.params.id, {
    $set: {
      nombre: req.body.nombre,
      edad: req.body.edad,
      telefono: req.body.telefono
    }
  }, {new: true}).then(resultado => {
    res.redirect(req.baseUrl);
  }).catch(error => {
    res.render('error', {error: "Error modificando contacto"});
  });
});

Subir ficheros en el formulario

  • Para subir ficheros en un formulario, el tipo de formulario debe ser multipart/form-data.
  • Dentro, habrá uno o varios campos de tipo file con los archivos que el usuario elegirá subir.
<form action="..." method="post" enctype="multipart/form-data">
  <input type="file" class="form-control" name="imagen">
</form>
  • Para procesar este tipo de formularios, se necesita una librería adicional llamada multer.
npm install multer
  • En los ficheros donde se necesite la subida de archivos, se debe incluir esta librería y configurar los parámetros de subida y almacenamiento:
const multer = require('multer');

let storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'public/uploads')
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + "_" + file.originalname)
  }
})

let upload = multer({storage: storage});
  • El elemento storage define la carpeta donde se subirán los archivos, en este ejemplo public/uploads, y qué nombre se asignará a los archivos al subirlos.
    • El atributo originalname del objeto file contiene el nombre original del archivo del cliente, pero para evitar sobreescrituras, se concatena como prefijo la fecha o timestamp actual con Date.now().
  • Se utiliza el middleware upload que se ha configurado.
  • Si en un servicio POST se espera recibir un archivo en un campo file llamado imagen, se puede hacer que automáticamente se suba a la carpeta especificada, aplicando el middleware en el servicio.
router.post('/', upload.single('imagen'), (req, res) => {
  // El archivo estará subido
  // Con req.file.filename se obtiene el nombre actual
  // Con req.body.XXX se obtienen el resto de campos
});

Subida de ficheros y method-override

  • Se utiliza el middleware method-override para sustituir comandos HTTP en una petición y usar los comandos PUT o DELETE aunque el formulario sea POST.
  • Cuando el formulario sube ficheros y es multipart/form-data, el procesamiento que se consigue con express.urlencoded no es suficiente.
  • Express no es capaz de reemplazar el método POST por PUT con method-override:
<form action="..." method="post" enctype="multipart/form-data">
  <input type="hidden" name="_method" value="put">
</form>
  • Para solucionar este problema se utiliza un middleware adicional como busboy-body-parser, pero tiene problemas de compatibilidad con otros middlewares como multer.
  • Una solución es reemplazar el servicio PUT del enrutador por otro POST al que se le pase la id del elemento a editar.
// Modificar contactos
// Lo definimos como "POST" para integrarlo mejor en un formulario multipart
router.post('/:id', (req, res) => {
  // El código interno del servicio no cambia
});

Validación de formularios

  • Una tarea importante al enviar formularios es la validación, que se puede hacer tanto en el cliente (con HTML5 y JavaScript) como en el servidor.
  • La validación en el servidor es importante, independientemente de si los datos se validan también en el cliente, como paso previo a su inserción en una base de datos.
  • Alternativas para realizar la validación de datos en el servidor:
    • Utilizar una librería básica como validator.js, que permite comprobar y corregir cadenas de texto.
    • Emplear una librería web como express validator
    • Utilizar los propios mecanismos de validación que ofrecen los esquemas de Mongoose.

Validación de textos con validator.js

  • La librería validator.js permite comprobar la validez de cadenas de texto y sanearlas.
  • Sanear es limpiar textos, eliminar espacios o escapar caracteres
  • Los datos que se reciben en una petición son textos, hasta que se procesan y almacenan en una base de datos.
  • Se debe instalar la librería con el comando npm install validator.
const validator = require('validator');

router.post('/', (req, res) => {
  let nombre = req.body.nombre;
  let telefono = req.body.telefono;

  if(validator.isEmpty(nombre) ||
  !validator.isLength(nombre, {min: 3}))
  {
    // Redirigir a página de error por el nombre
  }
  else if (!validator.isNumeric(telefono) ||
  !validator.isLength(telefono, {min: 9, max: 9}))
  {
    // Redirigir a página de error por el teléfono
  }
  else
  {
    // Correcto, hacer la inserción
  }
});

Validación de peticiones con express-validator

  • Para validar los datos de una petición en Node y Express se pueden utilizar librerías adicionales como express-validator.
    • Esta librería aglutina y amplía opciones ofrecidas por validator.js.
    • Se instala con el comando npm install express-validator.
  • Una vez instalada, se tienen a disposición validadores y saneadores.
  • Para utilizar los validadores, se debe acceder a los parámetros de la petición desde el cuerpo (body) o la query string (query).
  • Usando la libreria es posible comprobar si el nombre de un contacto no está vacío antes de una inserción.
const { body } = require('express-validator');

router.post('/', body('nombre').notEmpty(), (req, res) => {
  // Código habitual de inserción de contacto
});
  • Un middleware en el servicio POST accede con body('nombre') al valor enviado para el nombre y comprueba con el validador notEmpty que no esté vacío.
  • Si la validación se cumple se continúa con el proceso, y si no lo hace se interrumpe la petición.
  • Se puede limpiar espacios con el saneador trim tras la validación:
const { body } = require('express-validator');

router.post('/', body('nombre').notEmpty().trim(), (req, res) => {
  // Código habitual de inserción de contacto
});
  • Esta característica se denomina encadenamiento de validaciones (validation chain) y permite enlazar varias comprobaciones para un mismo dato en el proceso.

Validación de peticiones con los esquemas de Mongoose

  • En sesiones anteriores se configuran los esquemas de Mongoose para validar documentos en MongoDB
  • Se indica en los esquemas los mensajes de error a mostrar si la validación falla.
  • Se modifica el ejemplo de ContactosWeb_v2 en otra carpeta llamada ContactosWeb_v3 y se edita el fichero models/contacto.js.
const mongoose = require('mongoose');
// Definición del esquema de nuestra colección
let contactoSchema = new mongoose.Schema({
nombre: {
type: String,
required: [true, 'El nombre del contacto es obligatorio'],
minlength: [3, 'El nombre del contacto es demasiado corto'],
trim: true
},
telefono: {
type: String,
required: [true, 'El número de teléfono es obligatorio'],
unique: true,
trim: true,
match: [/^\d{9}$/, 'El teléfono debe constar de 9 dígitos']
},
edad: {
type: Number,
min: [18, 'La edad mínima debe ser 18'],
max: [120, 'La edad máxima debe ser 120']
}
});
// Asociación con el modelo (colección contactos)
let Contacto = mongoose.model('contacto', contactoSchema);
module.exports = Contacto;
  • Se añade un array con el valor y mensaje de error.

  • Se modifcan los servicios de inserción y borrado.

  • El elemento error.errors es un objeto con detalles sobre los errores de validación.

  • Object.keys(error.errors) devuelve un array de las claves (nombres de campo) presentes en error.errors.

  • Dentro del campo errors del error devuelto, se construye una respuesta que acumule los errores detectados.

  • Si no se detectan errores, se muestra un error genérico.

Studying That Suits You

Use AI to generate personalized quizzes and flashcards to suit your learning preferences.

Quiz Team

Related Documents

More Like This

Muster Station Signs
3 questions

Muster Station Signs

GoldForesight7167 avatar
GoldForesight7167
Creating a Muster Roll
10 questions

Creating a Muster Roll

SelfDeterminationBlueTourmaline6195 avatar
SelfDeterminationBlueTourmaline6195
Use Quizgecko on...
Browser
Browser