Cómo subir Archivos al Servidor usando JavaScript

JavascriptNode.js

En este tutorial vamos a ver cómo puedes subir archivos a un servidor que usa Node.js mediante JavaScript, lo cual es muy habitual. Por ejemplo, podrías querer subir un avatar, un thumbnail, un archivo PDF o cualquier otra imagen o archivo en diversos formatos.

Vamos a estructurar este tutorial en varias partes. Primero crearemos el proyecto, luego crearemos el código frontend y finalmente el código backend del servidor.

Para seguir este tutorial necesitarás ciertos conocimientos básicos de la línea de comandos. Si nunca la has utilizado, consulta el siguiente tutorial de la línea de comandos, en el que se explican ciertos comandos básicos para los sistemas operativos más utilizados. También necesitarás tener instalado tanto Node.js como el gestor de paquetes npm. Si no tienes estas herramientas instaladas, consulta el tutorial de instalación y configuración de Node.js y npm.

Creación del proyecto

Lo primero que vamos a hacer es configurar y crear el proyecto. Para ello, crea un directorio vacío en cualquier lugar, accede a su interior mediante la línea de comandos y usa el siguiente comando para crear el proyecto:

npm init

Tan solo necesitaremos instalar dos paquetes. Primero instala express mediante el siguiente comando:

npm install express

A continuación también necesitaremos un middleware de express llamado express-fileupload mediante el cual podremos gestionar los archivos que se envíen al servidor:

npm install express-fileupload

A continuación configura el archivo que creará el servidor de express. Para ello, edita el archivo package.json, que debería contener la línea "start": "node index.js" en la sección de scripts para así indicarle a Node el archivo que debe ejecutar cuando iniciemos la aplicación:

{
  "name": "subir-archivo-ajax",
  "description": "Tutorial en el que se sue un archivo medianta ajax",
  "version": "1.0.0",
  "dependencies": {
    "express": "4.16.2",
    "express-fileupload": "^1.1.7-alpha.3",
    "request": "^2.88.2"
  },
  "scripts": {
    "start": "node index.js"
  }
}

Seguidamente, crea el archivo index.js en la carpeta raíz del proyecto y agrega el código necesario para la creación de un servidor básico:

const express = require('express');
const router = express.Router();

const bodyParser = require('body-parser');
const fileupload = require('express-fileupload');
const FileController = require('./controllers/FileController');

const app = express();
const fileController = new FileController();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(fileupload());

router.post('/subir-archivo', fileController.subirArchivo);

router.use(function(req, res) {
    res.status(404).json({
        error: true,
        message: 'Not Found'
    });
});

app.use('/api', router);

app.use(express.static(__dirname));

app.get('/', function (req, res) {
    res.render('index.html');
});

var port = 3000;
app.listen(port, function () {
    console.log('Server', process.pid, 'listening on port', port);
});

module.exports = app;

Lo que hemos hecho es crear el servidor. En la parte superior del archivo hemos hecho un require del módulo 'express-fileupload', que es imprescindible para subir archivos.

Hemos incluido la clase FileController, localizada en el archivo /controllers/FileController.js, aunque todavía no la hemos creado. En la función subirArchivo de este controlador es en donde agregaremos el código encargado de subir el archivo.

En cuanto a la ruta que redirigirá la petición al controlador, hemos definido la ruta /api/subir-archivo mediante la siguiente función:

router.post('/subir-archivo', fileController.subirArchivo);

El prefijo de /api de la ruta lo hemos agregado usando la siguiente declaración:

app.use('/api', router);

Guarda este archivo, ya que a continuación crearemos el código frontend.

Código JavaScript Frontend

En este apartado agregaremos el código frontend encargado de enviar el archivo desde el sistema del usuario hasta el servidor. Para empezar, crea el archivo index.html en la carpeta raíz del proyecto. Seguidamente, editar el archivo que acabas de crear y copia y pega el siguiente código, que explicaremos más adelante:

<!DOCTYPE html>
<html lang="es">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="x-ua-compatible" content="ie=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Tutorial Subir Archivo Ajax Node</title>
  </head>
  <body>  
    <h1>Tutorial Subir Archivo Ajax Node</h1>
    <p><label>Selecciona un nuevo archivo!</label></p>
    <input type="file" id="subir_archivo" />
    <div id="resultado"></div>
    <script type="text/javascript" src="resources/js/scripts.js"></script>
  </body>
</html>

Lo que hemos hecho ha sido agregar una plantilla básica HTML5. Hemos agregado también un campo input HTML, que es el campo con el cual el usuario interactuará para subir el archivo:

<input type="file" id="subir_archivo" />"

Tal y como puedes ver, hemos enlazado al script /resources/js/scripts.js justo antes del cierre de la etiqueta </body>. Vamos a agregarlo, así que primero crea el directorio /resources/js y luego crea y edita el archivo scripts.js.

Ahora vamos a agregar el código JavaScript que nos permitirá asociar un evento al campo que hemos creado para así poder subir el archivo al servidor. Primero veremos el código y luego lo explicaremos:

const subirImagen= event => {
  const archivos = event.target.files;
  const data = new FormData();

  data.append('archivo', archivos[0]);

  fetch('/api/subir-archivo', {
    method: 'POST',
    body: data
  })
  .then(response => response.json())
  .then(data => {
    document.getElementById('resultado').innerHTML = 'El archivo ' + data.path + ' se ha subido correctamente.';
  })
  .catch(error => {
    console.error(error);
  });
}

document.querySelector('#subir_archivo').addEventListener('change', event => {
    subirImagen(event);
});

En el último bloque de código hemos registrado un evento change para el input que utilizamos para subir el archivo. En dicho evento ejecutamos la función subirImagen, que recibe como parámetro el propio evento del clic, desde donde tendremos acceso al archivo seleccionado.

Lo que hacemos en la función subirImagen es obtener el archivo seleccionado, localizado en el array event.target.files. Luego creamos un objeto FormData y le asignamos el archivo seleccionado. Finalmente usamos la función fetch para enviar una petición POST a la ruta /api/subir-archivo que hemos creado en el servidor. Si no conoces la API Fetch, puedes consultar el siguiente tutorial, en donde explico qué es un cómo se usa Fetch en JavaScript.

Seguidamente comprobamos si el envío del archivo se ha completado con éxito, imprimiendo en el campo resultado la ruta del archivo si este se ha subido correctamente, o mostrando un error en la consola en caso contrario. La ruta le devolvemos en la propiedad path.

Código Node.js Backend

Ahora vamos a ver el proceso que se sigue en el servidor para subir el archivo. Lo primero que debes hacer es crear el directorio /uploads en la carpeta raíz de tu proyecto. A este directorio es a donde subiremos los archivos.

Vamos a crear el archivo /controllers/FileController.js a modo de controlador. Al igual que antes, primero veremos el código de este archivo y luego explicaremos su funcionamiento:

class FileController
{
  subirArchivo = async (req, res, next) =>
  {
    const archivo = req.files.archivo;
    const fileName = archivo.name;
    const path = __dirname + '/../uploads/' + fileName;

    try {
      archivo.mv(path, (error) => {
        if (error) {
          console.error(error);
          res.writeHead(500, {
            'Content-Type': 'application/json'
          });
          res.end(JSON.stringify({ status: 'error', message: error }));
            return;
          }
          return res.status(200).send({ status: 'success', path:'/uploads/' + fileName });
       });
     } catch (e) {
       res.status(500).json({
         error: true,
         message: e.toString()
       });
     }
  }
}

module.exports = FileController;

Hemos creado una clase llamada FileController a modo de controlador, en la que hemos definido la función subirArchivo.

Lo primero que hacemos es obtener el archivo que hemos enviado, que debería estar en la variable req.files.archivo, ya que archivo era el nombre que le hemos dado en el código frontend. Ahora ya podemos obtener el nombre del archivo, que estará en la variable archivo.name.

Seguidamente hemos definido la ruta o path en la que vamos a copiar el archivo y luego, mediante al función archivo.mv, copiamos el archivo a dicha ruta.

En caso de que el archivo se haya copiado correctamente, enviaremos la respuesta de vuelta en formato JSON:

return res.status(200).send({ status: 'success', path:'/uploads/' + fileName });

En caso contrario, devolvemos un error.

Probando la aplicación

Vamos a probar la aplicación para verificar que todo funciona correctamente. Para ello, abre una ventana de terminal y sitúate en la carpeta raíz del proyecto. Luego ejecuta el siguiente comando para iniciar el servidor:

npm start

Seguidamente accede a la URL http://localhost:3000/ y prueba a subir algún archivo, como por ejemplo una imagen en formato .png o .jpg.

Código en GitHub

Si quieres ver el código completo de este ejemplo, puedes encontrarlo en el siguiente enlace:

Y esto ha sido todo.


Avatar de Edu Lazaro

Edu Lázaro: Ingeniero técnico en informática, actualmente trabajo como desarrollador web y programador de videojuegos.

👋 Hola! Soy Edu, me encanta crear cosas y he redactado esta guía. Si te ha resultado útil, el mayor favor que me podrías hacer es el de compatirla en Twitter 😊

Si quieres conocer mis proyectos, sígueme en Twitter.

2 comentarios en “Cómo subir Archivos al Servidor usando JavaScript

  1. interesante , una duda y como harías para enviar un grafico svg generado por un timeline chart hacia un servidor ,¿ esto tendría que ser llamado desde el servidor ?
    o por otro lado como harias para poner un svg dentro de un y tenga un enlace sin descargar el grafico svg sino manipular dentro del script?

  2. Hola, muy interesante ahora como hago para subir un archivo y que el nombre lo seleccione el usuario desde un combo por ejemplo de 3 opciones, y asignarle dicho nombre de lo seleccionado.

    Saludos desde Mexico

Responder a crisxman Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

“- Hey, Doc. No tenemos suficiente carretera para ir a 140/h km. - ¿Carretera? A donde vamos, no necesitaremos carreteras.”