La API de archivos en JavaScript: cómo leer, validar y manipular archivos en el navegador
- 👤 Andrés Cruz
La API de archivos en JavaScript se ha convertido en una pieza clave para muchas aplicaciones web modernas. En mi experiencia desarrollando aplicaciones que manejan altos volúmenes de archivos, poder inspeccionar y validar los datos antes de enviarlos al servidor marca una diferencia enorme tanto en rendimiento como en experiencia de usuario.
Hace algunos años, este tipo de validaciones solo se podían hacer del lado del backend. Hoy, gracias a la API de archivos de HTML5, gran parte de ese trabajo puede resolverse directamente en el navegador, ahorrando tiempo, recursos y errores innecesarios.
En este artículo voy a explicarte qué es la API de archivos en JavaScript, cómo funciona y, sobre todo, cómo usarla de forma práctica para leer, validar, previsualizar y hasta generar archivos sin pasar por el servidor.
Anteriormente vimos como reconocer la voz con SOLO JavaScript.
¿Qué es la API de archivos en JavaScript y para qué se utiliza?
La File API es un conjunto de interfaces introducidas con HTML5 que permiten a las aplicaciones web acceder a archivos locales seleccionados por el usuario. Esta API no da acceso libre al sistema de archivos (por razones de seguridad), sino únicamente a los archivos que el propio usuario decide cargar.
Con ella es posible:
- Obtener metadatos de un archivo (nombre, tamaño, tipo MIME).
- Leer el contenido de archivos de texto, imágenes, audio, etc.
- Previsualizar archivos antes de subirlos.
- Validar archivos sin enviarlos al servidor.
- Crear archivos descargables desde JavaScript.
Ventajas de procesar archivos desde el lado del cliente
Cuando he trabajado en formularios donde los usuarios suben decenas de archivos, validar desde el navegador evita subir archivos incorrectos, demasiado grandes o con un formato inválido. Esto se traduce en:
- Menor carga en el servidor.
- Respuesta inmediata al usuario.
- Mejor experiencia de uso.
- Menos errores en procesos posteriores.
Compatibilidad de la API de archivos con los navegadores
La API de archivos está soportada por todos los navegadores modernos, pero sigue siendo buena práctica comprobar su disponibilidad antes de usarla.
Cómo comprobar soporte de File, FileList y FileReader
Una validación sencilla es comprobar la existencia de las interfaces principales.
Al ser una tecnología provista a partir de la API de HTML5 puede sufrir cambios de una versión a otra de los navegadores; por lo tanto, es necesario validar que el navegador realmente cuente con el soporte correspondiente a esta API.
Para verificar la compatibilidad podemos emplear el siguiente código JavaScript:
if (!(window.File && window.FileList && window.FileReader)) {
console.log('La API de archivos no está soportada en este navegador');
return;
}Este tipo de chequeo es algo que suelo añadir siempre al inicio, sobre todo si la aplicación debe funcionar en entornos controlados o navegadores antiguos.
Propiedades de los archivos en JavaScript
Una vez que el usuario selecciona un archivo, JavaScript lo representa mediante un objeto File. Este objeto expone varias propiedades de solo lectura muy útiles para validaciones.
Nombre, tamaño, tipo MIME y fecha de modificación
Las propiedades más importantes son:
- file.name → nombre del archivo.
- file.size → tamaño en bytes.
- file.type → tipo MIME (image/png, text/plain, etc.).
- file.lastModified → timestamp de la última modificación.
Con solo estas propiedades ya puedes, por ejemplo, impedir que se suban archivos mayores a cierto tamaño o con extensiones no permitidas, algo que en la práctica evita muchos problemas.
Se referencia el objeto Filelist aunque este no se emplee directamente por este nombre, permite retornar una lista de los archivos seleccionados (por ejemplo) en un input type="file".
Selección de archivos con input type="file"
La forma más común de trabajar con la API de archivos es mediante un campo HTML:
<input type="file" id="files" multiple>Selección múltiple de archivos
El atributo multiple permite seleccionar varios archivos a la vez. Esto es especialmente útil en aplicaciones de carga masiva.
const input = document.getElementById('files');
input.addEventListener('change', function () {
const files = this.files;
for (let i = 0; i < files.length; i++) {
const file = files[i];
console.log(
file.name,
file.type || 'n/a',
file.size,
file.lastModified
);
}Obtener y mostrar información de los archivos
const input = document.getElementById('files');
input.addEventListener('change', function () {
const files = this.files;
for (let i = 0; i < files.length; i++) {
const file = files[i];
console.log(
file.name,
file.type || 'n/a',
file.size,
file.lastModified
);
}
});En más de un proyecto he usado este enfoque para mostrar al usuario un resumen claro de lo que está a punto de subir antes de confirmar la operación.
Datos de los archivos
Resulta indispensable para las aplicaciones web que manejen un alto volúmenes de archivos al momento de su carga por parte del usuario; poder validar o verificar los datos del archivo que lo conforman el archivo; antes teníamos que cargar el archivo para que desde el lado del servidor realizar estas validaciones; ahora también es posible realizar parte de estas validaciones desde el lado del cliente con la API de archivos en JavaScript.
Hasta la fecha se han hablado de algunas APIs JavaScript que permiten realizar múltiples funciones y que sin ellas sería muy difíciles de hacer; ahora veremos cómo trabajar con parte de la API de archivos en JavaScript; veremos como se puede obtener datos de archivos que se encuentren cargados localmente a través del input type="file" y derivados.
Obteniendo acceso a los archivos de usuario
El método más común para cargar los archivos en un aplicación es mediante el uso de la etiqueta input type="file"; una vez cargador con ayuda de la API de archivos podemos obtener un lista de archivos cargados por el usuario su información.
La API de archivos soporta al 100% el atributo multiples presentes en la etiqueta input type="file".
Mostrando los datos de archivos cargados en un input type="file" multiple
El siguiente ejemplo permite mostrar la distinta información obtenible mediante la API de archivos seleccionados por un input type="file" multiple:
if (!(window.FileList)) {
console.log('La API FileList no está soportada');
return;
}
var files = document.getElementById('files').files;
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li>', escape(f.name), '(', f.type || 'n/a', ') - ',
f.size, ' bytes, last modified: ',
f.lastModifiedDate.toLocaleDateString(), '</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
Mostrando los datos de archivos cargador mediante Drag and Drop
El siguiente ejemplo es una variación del anterior, y podemos emplear el Drag and Drop para la carga del archivo y posteriormente mostrar la información del archivo:
function drop(event) {
event.stopPropagation();
event.preventDefault();
if (!(window.FileList)) {
console.log('La API FileList no está soportada');
return;
}
var files = event.dataTransfer.files;
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li>', escape(f.name), '(', f.type || 'n/a', ') - ',
f.size, ' bytes, última modificación: ',
f.lastModifiedDate.toLocaleDateString(), '</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
function dragenter(event) {
event.stopPropagation();
event.preventDefault();
}
function dragover(event) {
event.stopPropagation();
event.preventDefault();
}
var contenedor = document.getElementById("contenedor");
contenedor.addEventListener("dragenter", dragenter, false);
contenedor.addEventListener("dragover", dragover, false);
contenedor.addEventListener("drop", drop, false);El ejemplo mas sencillo:
function dragover(e) {
e.preventDefault();
}
function drop(e) {
e.preventDefault();
const files = e.dataTransfer.files;
handleFiles(files);
}
const dropzone = document.getElementById('dropzone');
dropzone.addEventListener('dragover', dragover);
dropzone.addEventListener('drop', drop);Lectura del contenido de archivos con FileReader
Poder acceder al contenido de los archivos cargados en una página web, o lo que es lo mismo, permitir la lectura de los archivos cargados en la aplicación web mediante una API JavaScript nativa abre una enorme cantidad de posibilidades para la creación de aplicaciones web para el manejo de archivos y edición de los mismo.
Se puede cargar archivos texto planos para la edición del texto que lo conforma, validar el contenido, mostrar previews, etc y todo esto desde el lado del cliente sin necesidad de conectarse a otro servidor.
Anteriormente explicamos las distintas propiedades que existen en la API de archivos en JavaScript para obtener datos de los archivos; ahora iremos un poco más allá para llegar a su apertura para una posterior lectura de los archivos cargados mediante input type="file" u otros métodos como el Drag and Drop.
Para leer el contenido de un archivo se utiliza la interfaz FileReader, que trabaja de forma asíncrona.
readAsText vs readAsDataURL vs readAsArrayBuffer
Los métodos más usados son:
- readAsText: ideal para archivos .txt, .csv, .json.
- readAsDataURL: perfecto para imágenes y previsualizaciones.
- readAsArrayBuffer: útil para trabajar con datos binarios.
Elegir bien el método es importante. En aplicaciones reales, usar el método incorrecto puede complicar innecesariamente el procesamiento.
Eventos de FileReader y control de errores
El evento más común es onload, que se dispara cuando el archivo ha sido leído correctamente.
const reader = new FileReader();
reader.onload = function (e) {
console.log(e.target.result);
};1.0 Verificando la compatibilidad con el navegador
Antes que nada y al igual que cualquier nueva tecnología se recomienda verificar que el navegador cuente con soporte emplear la API; se debe de hacer referencia a la interfaz File en vez de la interfaz FileList la cual proporciona datos del archivo de solo lectura como su nombre y más importante del contenido del mismo.
Para verificar la compatibilidad podemos emplear el siguiente código JavaScript:
if (!(window.File)) {
console.log('La API File no está soportada'); return;
}Garantizado el soporte de la API de archivos (window.File) por el navegador, ahora si es posible emplear los distintos métodos y propiedades que cuenta la API de archivos para la lectura del mismo.
2.0 Obteniendo archivos del usuario
El método más común para obtener archivos por parte del usuario es mediante la etiqueta input type="file"; aunque sirve cualquier API que retorne el listado de los archivos y el contenido de estos serán accedidos con la API de archivos como el experimento de Drag and Drop que vimos anteriormente.
Es posible obtener múltiple información sobre la lista de archivos que actualmente fueran cargados (soporta el atributo multiples).
3.0 la interfaz FileReader para la lectura de los archivos
Esta interfaz nos provee de métodos para la lectura de los archivos como:
FileReader.readAsBinaryString(Blob|File): Se debe especificar el archivo o blob la propiedad result contendrá los datos del archivo/objeto BLOB en forma de cadena binaria. Cada byte se representa con un número entero comprendido entre 0 y 0,255, ambos incluidos.FileReader.readAsText(Blob|File, [opt_encoding]): Se debe especificar el archivo o blob y opcionalmente el encoding que por defecto es UTF-8; el archivo debe ser de texto plano.FileReader.readAsDataURL(Blob|File): Se debe especificar el archivo o blob y el contenido debe de estar codificado en base64.
Todos estos métodos tienen en común el pase del archivo como parámetros para poder acceder a su contenido, una vez que se acceda a su contenido y fuera leído el contenido se dispara el evento loadend.
Aunque para los ejemplos presentados (los cuales se asumen serán de texto plano) nos serviría emplear cualquiera de los métodos vistos anteriormente aunque algunos retornen el MIME entre otras cosas.
Si quieres obtener más información, no dudes en consultar a la MDN: FileReader.
3.1 Eventos de la interfaz FileReader
El evento loadend se dispara luego de que la lectura del archivo es exitosa y desde aquí se accede al contenido del archivo y hacer algo con el mismo.
Lectura de archivos capturados mediante un input type="file"
El uso más básico o común que se nos ocurre es capturar el archivo seleccionado por un input type="file" y mostrar el contenido de este:
var MAX_BYTES = 102400; // 100 KB
function filesInfo(event) {
if (!(window.File)) {
console.log('La API File no está soportada');
return;
}
var file;
var reader;
var files = document.getElementById('files').files;
for (var i = 0; i < files.length; i++) {
file = files[i];
reader = new FileReader();
reader.onloadend = onFileLoaded;
reader.readAsBinaryString(file);
}
}
function onFileLoaded(event) {
document.getElementById("resultado").innerHTML = event.currentTarget.result.substr(0, MAX_BYTES);
}
Vemos que la estructura es similar a los vistos en la entrada anterior: a excepción que ahora empleamos el método FileReader para la lectura de los archivos y la posterior llamada del evento onloadend al finalizar la lectura; finalmente el experimento:
Leer archivos desde un input file más sencillo:
document.getElementById('files').addEventListener('change', function () {
const file = this.files[0];
const reader = new FileReader();
reader.onload = function (e) {
console.log(e.target.result);
};
reader.readAsText(file);
});Este patrón es uno de los más comunes y, en mi experiencia, suficiente para la mayoría de validaciones y previsualizaciones de texto.
Lectura de archivos capturados mediante el Drag and Drop
El último ejemplo consiste en adaptar el experimento visto anteriormente con el Drag and Drop empleando todos los eventos del Drag and Drop hasta la captura del archivo en el evento drop():
var MAX_BYTES = 102400; // 100 KB
function dragenter(event) {
event.stopPropagation();
event.preventDefault();
}
function dragover(event) {
event.stopPropagation();
event.preventDefault();
}
function drop(event) {
console.log('drop', event);
event.stopPropagation();
event.preventDefault();
var data = event.dataTransfer;
var files = data.files;
var file;
var reader;
for (var i = 0; i < files.length; i++) {
file = files[i];
reader = new FileReader();
reader.onloadend = onFileLoaded;
reader.readAsText(file);
}
}
function onFileLoaded(event) {
document.getElementById("resultado").value = event.currentTarget.result.substr(0, MAX_BYTES);
}
var contenedor = document.getElementById("contenedor");
contenedor.addEventListener("dragenter", dragenter, false);
contenedor.addEventListener("dragover", dragover, false);
contenedor.addEventListener("drop", drop, false);
Leer archivos usando Drag and Drop más sencillo:
function handleFiles(files) {
for (let i = 0; i < files.length; i++) {
const reader = new FileReader();
reader.onload = function (e) {
console.log(e.target.result);
};
reader.readAsText(files[i]);
}
}Creando un archivo descargable con JavaScript
Generalmente cuando se desea descargar un archivo de una aplicación web se debe realizar una petición al servidor por el archivo en cuestión para posteriormente pueda ser descargado a través del navegador del usuario; con unas pocas líneas de código y empleando los data URIs es posible crear archivos para que sean descargados sin la necesidad de realizar este tipo de peticiones; el código JavaScript que veremos a continuación permite generar un archivo de texto plano (TXT) a partir de un contenido de un campo de texto; específicamente de un textarea para luego pueda ser descargado; primero veremos como armar un data URI:
Sintaxis de los data URIs
Los data URIs permiten embeber contenidos en pequeños archivos; tomando un extractor de la documentación oficial que ofrece la MDN sobre los data URIs cumplen la siguiente sintaxis:
data:[<mediatype>][;base64],<data>| <mediatype> | Permite indicar el tipo de archivo como:
|
| ;base64 (opcional) | Si son datos planos o textuales simplemente se embebe el texto; de otra forma de debe de especificar ;base64 para embeber datos binarios como las imágenes o videos. |
Paso siguiente se indica la data del archivo; ejemplo:
data:,Hello%2C%20World!Corresponde a un archivo de texto plano.
Script para generar y descargar archivos
<textarea id="txt"></textarea>
<a href="#" id="link" download="contenido.txt">Descargar el contenido del textarea</a> window.onload = function() {
var txt = document.getElementById('txt');
txt.value = window.onload + '';
document.getElementById('link').onclick = function(code) {
this.href = 'data:text/plain;charset=utf-8,'
+ encodeURIComponent(txt.value);
};
};¿Cómo funciona el script para generar y descargar archivos?
El corazón del script:
document.getElementById('link').onclick = function(code) {
this.href = 'data:text/plain;charset=utf-8,'
+ encodeURIComponent(txt.value);
};La función encodeURIComponent() codifica la cadena de texto y la embebe dentro del atributo href del enlace para su descarga a través del atributo download del mismo enlace al detectar un clic.
Casos de uso reales de la API de archivos en aplicaciones web
Algunos usos muy comunes en proyectos reales:
- Validar tamaño y tipo de archivo antes de subirlo.
- Mostrar previews de imágenes.
- Leer archivos CSV para importar datos.
- Editar archivos de texto directamente en el navegador.
- Generar archivos descargables al vuelo.
En todos estos escenarios, la API de archivos permite crear experiencias mucho más rápidas y amigables.
Preguntas frecuentes sobre la API de archivos en JavaScript
- ¿JavaScript puede leer cualquier archivo del sistema?
- No. Solo puede acceder a los archivos que el usuario selecciona explícitamente.
- ¿Es segura la API de archivos?
- Sí. Los navegadores imponen restricciones muy estrictas para proteger al usuario.
- ¿Puedo leer archivos grandes?
- Sí, pero conviene validar el tamaño y limitar la lectura para evitar problemas de rendimiento.
- ¿Funciona en todos los navegadores?
- Funciona en todos los navegadores modernos.
Conclusiones
La API de archivos en JavaScript abre un abanico enorme de posibilidades para el manejo de archivos directamente en el navegador. Desde simples validaciones hasta lectura avanzada y generación de archivos, esta API permite reducir dependencias del servidor y mejorar notablemente la experiencia del usuario.
En aplicaciones con muchos archivos, procesar parte del trabajo en el cliente no es solo una mejora: es casi una necesidad.
Acepto recibir anuncios de interes sobre este Blog.
Aprende qué es la API de archivos en JavaScript, cómo leer, validar y manipular archivos locales con ejemplos prácticos usando File, FileReader y Drag and Drop.