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.
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 obcionalmente 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:
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);
Otros enlaces de interés
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter