W3docs

File API

La File API de JavaScript permite a los desarrolladores web interactuar con archivos del lado del cliente: seleccionar, leer y manipular archivos en aplicaciones web.

File API en JavaScript: Interacción con archivos del usuario

La File API en JavaScript es una herramienta poderosa que permite a los desarrolladores web interactuar con archivos del lado del cliente, posibilitando que los usuarios seleccionen, lean y manipulen archivos dentro de aplicaciones web. Esta API tiene diversas aplicaciones, entre ellas la carga de archivos, el procesamiento de contenido generado por el usuario y la realización de operaciones relacionadas con archivos. En este artículo exploraremos qué es la File API, sus ventajas, cuándo utilizarla y algunos casos de uso habituales.

¿Qué es la File API?

La File API es una API de JavaScript que proporciona acceso a los archivos seleccionados por el usuario a través de campos de entrada de archivos (<input type="file">) o archivos arrastrados sobre páginas web. Expone un pequeño conjunto de interfaces que trabajan juntas:

  • File — representa un único archivo elegido por el usuario. Contiene metadatos como name, size (en bytes), type (tipo MIME) y lastModified (una marca de tiempo). Un File es un tipo especial de Blob.
  • Blob — un fragmento de datos binarios inmutables ("Binary Large Object"). Todo File es un Blob, pero también puedes construir tus propios blobs para descargar o subir. Consulta el capítulo dedicado de JavaScript Blob para más información.
  • FileList — la colección similar a un array que devuelve input.files. Se puede indexar con [0] o iterar sobre ella.
  • FileReader — un lector asíncrono que carga el contenido de un archivo en memoria como texto, una URL de datos o un ArrayBuffer.

Dado que todo esto se ejecuta en el navegador, puedes inspeccionar, validar y previsualizar archivos antes de que nada llegue a un servidor.

La File API solo lee los archivos que el usuario te entrega explícitamente. Una página nunca puede abrir en silencio archivos arbitrarios del disco del visitante — ese es un límite de seguridad deliberado.

Métodos de lectura de un vistazo

FileReader expone cuatro métodos de lectura. Elige el que se ajuste al resultado que necesitas:

MétodoTipo de resultadoUso habitual
readAsText(file)string.txt, .csv, .json, código fuente
readAsDataURL(file)URL string data:vistas previas de imágenes/audio/vídeo mediante src
readAsArrayBuffer(file)ArrayBufferanálisis binario, hashing, inspección de bytes
readAsBinaryString(file)string de bytesuso heredado; prefiere readAsArrayBuffer

Los navegadores modernos también exponen atajos basados en promesas directamente sobre el blob: await file.text(), await file.arrayBuffer() y file.stream(). Estos suelen reemplazar a FileReader en código nuevo y se combinan de forma natural con async/await.

Cuándo usar la File API

La File API es especialmente útil cuando quieres:

  1. Gestionar cargas de archivos — permitir que los usuarios seleccionen y envíen archivos desde sus dispositivos.
  2. Previsualizar archivos — mostrar una miniatura de una imagen elegida, o el texto de un documento, antes de subirlo.
  3. Validar en el cliente — rechazar el tipo MIME incorrecto o un archivo demasiado grande antes de gastar ancho de banda en una carga.
  4. Manipular archivos localmente — recortar imágenes, editar texto o analizar CSV sin un viaje de ida y vuelta al servidor.

En el caso de los PDF conviene tener en cuenta una advertencia: la File API no genera PDFs. Solo selecciona, lee y guarda archivos. Para crear un PDF necesitas una biblioteca como jsPDF, y la File API (mediante un Blob) puede entonces activar la descarga.

Ejemplo básico: Lectura del contenido de un archivo

A continuación se muestra un ejemplo sencillo que usa la File API en JavaScript para leer un archivo de texto seleccionado por el usuario y mostrar su contenido. Esta demostración te ayudará a entender cómo interactuar con archivos de tus dispositivos usando tecnologías web.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>File Reader Example</title>
  </head>
  <body>
    <h1>Read Text File</h1>
    <p>First, choose a text file, then click the 'Read File' button to see your file's contents.</p>
    <input type="file" id="fileInput" accept=".txt" />
    <button onclick="readFile()">Read File</button>
    <pre id="fileContents"></pre>

    <script>
      function readFile() {
        const fileInput = document.getElementById("fileInput");
        const file = fileInput.files[0]; // Get the first file selected by the user

        if (file) {
          const reader = new FileReader();

          reader.onload = function (e) {
            const contents = e.target.result;
            document.getElementById("fileContents").textContent = contents;
          };

          reader.onerror = function (e) {
            console.error("Error reading file:", e.target.error.message);
          };

          reader.readAsText(file); // Read the file as text
        } else {
          alert("Please select a file.");
        }
      }
    </script>
  </body>
</html>

En este código:

  • Selección del archivo: El usuario selecciona un archivo de texto (un archivo con extensión .txt) mediante el elemento de entrada de archivo.
  • Lectura del archivo: Cuando el usuario hace clic en el botón "Read File", el archivo seleccionado se lee como texto. Ten en cuenta que las operaciones de FileReader son asíncronas; el callback onload se ejecuta solo después de que el archivo se ha leído por completo.
  • Visualización del archivo: El contenido del archivo se muestra en un elemento <pre>, conservando el formato del archivo de texto.

Este ejemplo proporciona una demostración sencilla de la capacidad de la File API para leer e interactuar con archivos seleccionados por el usuario en una aplicación web.

Inspección de los metadatos de un archivo

A menudo necesitas los detalles de un archivo antes de hacer cualquier otra cosa — para validarlo o para mostrar al usuario lo que ha elegido. Cada objeto File expone estos metadatos de forma síncrona, sin necesidad de lectura:

const file = fileInput.files[0];

console.log(file.name);          // e.g. "report.pdf"
console.log(file.type);          // MIME type, e.g. "application/pdf"
console.log(file.size);          // size in bytes, e.g. 12048
console.log(file.lastModified);  // ms since the Unix epoch

Una tarea habitual consiste en convertir el número de bytes en algo legible para el ser humano:

function formatBytes(bytes) {
  if (bytes === 0) return "0 B";
  const units = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(1024));
  return (bytes / Math.pow(1024, i)).toFixed(1) + " " + units[i];
}

console.log(formatBytes(0));        // "0 B"
console.log(formatBytes(900));      // "900.0 B"
console.log(formatBytes(2048));     // "2.0 KB"
console.log(formatBytes(5242880));  // "5.0 MB"

Validación de archivos antes de la carga

La validación en el cliente ofrece retroalimentación inmediata al usuario y evita cargas innecesarias. Recuerda volver a validar también en el servidor — las comprobaciones del cliente son una comodidad, no una garantía de seguridad, ya que cualquiera puede saltárselas.

function validateImage(file) {
  const allowedTypes = ["image/png", "image/jpeg", "image/webp"];
  const maxSize = 2 * 1024 * 1024; // 2 MB

  if (!allowedTypes.includes(file.type)) {
    return "Only PNG, JPEG, or WebP images are allowed.";
  }
  if (file.size > maxSize) {
    return "File is too large (max 2 MB).";
  }
  return null; // null means "valid"
}

// Simulate two checks:
console.log(validateImage({ type: "image/gif", size: 1000 }));
// "Only PNG, JPEG, or WebP images are allowed."
console.log(validateImage({ type: "image/png", size: 500 }));
// null

Previsualización de una imagen antes de la carga

Para mostrar una miniatura de la imagen elegida, léela como una URL de datos y asigna esa cadena al atributo src de un elemento <img>. El navegador decodifica el payload en base64 directamente — sin involucrar al servidor.

<input type="file" id="imageInput" accept="image/*" />
<img id="preview" alt="Preview" width="200" />

<script>
  const input = document.getElementById("imageInput");
  const preview = document.getElementById("preview");

  input.addEventListener("change", () => {
    const file = input.files[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = (e) => {
      preview.src = e.target.result; // a "data:image/...;base64,..." URL
    };
    reader.readAsDataURL(file);
  });
</script>

Para archivos multimedia grandes, prefiere URL.createObjectURL(file) en lugar de una URL de datos — devuelve una referencia blob: corta sin copiar el archivo completo en una cadena. Recuerda llamar a URL.revokeObjectURL() cuando la vista previa ya no sea necesaria para que el navegador pueda liberar la memoria.

Lectura de un archivo con promesas modernas

En los navegadores actuales puedes omitir FileReader por completo y usar await con los métodos propios del blob. Esto resulta más limpio cuando ya estás dentro de una función async:

async function readTextFile(file) {
  const text = await file.text();
  return text.trim().split("\n").length; // count of lines
}

// Simulate a File with the same API as the real Blob:
const fakeFile = new Blob(["line 1\nline 2\nline 3"]);
readTextFile(fakeFile).then((lines) => console.log(lines)); // 3

Carga de un archivo a un servidor

Una vez seleccionado el archivo, puedes enviarlo con fetch y un cuerpo FormData. El navegador establece las cabeceras multipart/form-data correctas automáticamente — no configures Content-Type tú mismo:

async function uploadFile(file) {
  const formData = new FormData();
  formData.append("upload", file, file.name);

  const response = await fetch("/api/upload", {
    method: "POST",
    body: formData,
  });
  return response.ok;
}

Consulta el capítulo Fetch API para conocer el modelo completo de solicitud/respuesta.

Errores comunes

  • FileReader es asíncrono. El resultado solo está disponible dentro de onload; leer reader.result en la línea siguiente devuelve null.
  • input.files puede contener múltiples archivos. Añade el atributo multiple al input e itera sobre el FileList; de lo contrario solo verás files[0].
  • El value se borra al cancelar en algunos navegadores. Volver a seleccionar el mismo archivo puede no disparar change; restablece input.value = "" primero si necesitas detectarlo.
  • file.type puede estar vacío. Para extensiones desconocidas el tipo MIME puede ser ""; nunca confíes en él como única comprobación.
  • Las URL de objeto generan fugas de memoria. Cada URL.createObjectURL() debe ir acompañado de un URL.revokeObjectURL().

Conclusión

La File API en JavaScript permite a los desarrolladores web trabajar con archivos del usuario directamente en aplicaciones web, abriendo posibilidades para mejorar las interacciones del usuario y ofrecer una experiencia fluida. Ya sea que estés creando un cargador de archivos, un editor de documentos o cualquier aplicación que requiera manipulación de archivos, la File API te proporciona las herramientas para crear soluciones de gestión de archivos del lado del cliente con funcionalidades avanzadas.

Para profundizar más, explora el capítulo JavaScript Blob para construir y descargar tus propios datos binarios, Drag and Drop con JavaScript para permitir que los usuarios arrastren archivos sobre la página, y Fetch API para enviar archivos a un servidor.

Practice

Práctica
¿Qué puedes hacer con la File API en JavaScript?
¿Qué puedes hacer con la File API en JavaScript?
Was this page helpful?