Movatterモバイル変換


[0]ホーム

URL:


  1. Tecnología web para desarrolladores
  2. API web
  3. File API
  4. Utilizar ficheros desde aplicaciones web

Esta página ha sido traducida del inglés por la comunidad.Aprende más y únete a la comunidad de MDN Web Docs.

View in EnglishAlways switch to English

Utilizar ficheros desde aplicaciones web

El uso de la API File añadida al DOM en HTML5, ahora hace posible que la página web solicite al usuario que seleccione archivos locales y, a continuación, leer el contenido de esos archivos. Esta selección se puede hacer, ya sea usando un elemento<input> de HTML o mediante arrastrar y soltar.

Selección de ficheros utilizando HTML

Seleccionar solo un fichero usando la API File es sencillo:

<input type="file" onchange="handleFiles(this.files)">

Cuando el usuario elige el fichero, la funciónhandleFiles() es llamada con un objetoFileListel cual a su vez contiene un objetoFile que representa el fichero elegido por el usuario.

Si se prefiere permitir al usuario elegir varios ficheros, entonces se pone el atributomultiple en el elementoinput:

<input type="file" multiple="true" onchange="handleFiles(this.files)">

En este caso, la lista de ficheros pasada a la funciónhandleFiles() contiene un objetoFile por cada fichero seleccionado por el usuario.

Comenzando en Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1), se puede ocultar el realmente feo<input> y representar tu propio interfaz para abrir el picker de ficheros y pintar que fichero o ficheros ha seleccionado el usuario. Esto se puede hacer añadiendo al elemento input la característica "display:none" en su css, o estilo y llamando al métodoclick() del elemento<input>.

Como aparece en este HTML:

<form>  <input type="file" multiple accept="image/*" onchange="handleFiles(this.files)"></form><a href="#">Select some files</a>

Tu métododoClick() puede parecerse al siguiente:

function doClick() {  var el = document.getElementById("fileElem");  if (el) {    el.click();  }}

Obviamente puedes cambiar como quieras, el estilo del botón para abrir el picker de ficheros.

Añadir dinámicamente un listener tipo change

Si tu campo input ha sido creado usando una libreria JavaScript comojQuery, se necesitará usarelement.addEventListener() para añadir el manejador de eventos tipo change, como en el ejemplo siguiente:

var inputElement = document.getElementById("inputField");inputElement.addEventListener("change", handleFiles, false);function handleFiles() {  var fileList = this.files;  /* now you can work with the file list */}

Nota: en este caso, la funciónhandleFiles() mira la lista de ficheros con la finalidad de aceptar un parametro, mientras los eventos listeners sean añadidos de esta manera no pueden aceptar un parametro del input.

Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) introduce soporte para los métodos de DOMwindow.createBlobURL() ywindow.revokeBlobURL(). El cual te permite crear un simple string con la URL que referenciar cualquier dato que pueda referenciar usando un objetoFile DOM, esto incluye los ficheros locales del usuario del dispositivo.

Cuando tienes un objetoFile te gusta poder referenciarlo con una URL desde el HTML, la manera de crear tu propio blob URL para poder hacer esto es la siguiente:

var blobURL = window.createBlobURL(fileObj);

El blob URL es un string que identifica el objetoFile. Cada vez que se llama awindow.createBlobURL(), un único blob URL se crea. Cada vez que esto pasa debe de ser liberado. Cuando el documento se cierra, se libera automáticamente, pero si tu página lo usa dinámicamente deberás liberarlos explicitamente llamando awindow.revokeBlobURL():

window.revokeBlobURL(blobURL);

Selección de ficheros usando drag and drop

También se puede dejar al usuario arrastrar los ficheros en tu aplicación web.

El primer paso para establecer la zona de arrastre, el lugar en donde dejar los ficheros arrastrados. La parte exacta en donde se coloque esta zona de arrastre dentro de tu aplicación, dependerá del diseño de la aplicación, pero crear el elemento es sencillo:

var dropbox;dropbox = document.getElementById("dropbox");dropbox.addEventListener("dragenter", dragenter, false);dropbox.addEventListener("dragover", dragover, false);dropbox.addEventListener("drop", drop, false);

En este ejemplo se transforma el elemento de ID "dropbox" en la zona de arrastre. Esto se hace añadiendo listeners para lo eventos dedragenter,dragover, ydrop.

Realmente en este caso no se necesita hacer nada con los eventosdragenter ydragover, por lo que ambas funciones seran muy sencillas. Sólo pararán la propagacion de eventos y prevendran las acciones por defecto:

function dragenter(e) {  e.stopPropagation();  e.preventDefault();}function dragover(e) {  e.stopPropagation();  e.preventDefault();}

La verdadera magia ocurre en la funcióndrop():

function drop(e) {  e.stopPropagation();  e.preventDefault();  var dt = e.dataTransfer;  var files = dt.files;  handleFiles(files);}

Aquí se recupera el campodataTransfer del evento, a partir de ahi se extraen la lista de ficheros, y se pasan ahandleFiles(). A partir de este punto se manejan los ficheros de igual manera tanto si se han obtenido usado el elementoinput o drag and drop.

Recuperando la información de los ficheros selecionados

El objetoFileList es dado por el DOM y lista todos los ficheros selecionados por el usuario, cada uno es un objetoFile. Para determinar el número de ficheros que han sido seleccionados se comprueba la longitud de la lista con el atributolength:

var numFiles = files.length;

Al objetoFile se accede de manera sencilla, accediendo a la lista como si fuera un array:

for (var i = 0; i < files.length; i++) {  var file = files[i];  ..}

El bucle itera por todos los ficheros de la lista.

Cada objetoFile tiene tres atributos que contienen información util sobre el fichero.

name

Es de solo lectura y es el nombre del fichero sin ninguna información sobre el path.

size

Es de solo lectura y es el tamaño del fichero en bytes como un entero de 64-bit.

type

Es de solo lectura y contiene MIME type del fichero, o "" si el tipo no puede ser determinado.

Ejemplo: Mostrando miniaturas de una selección de imágenes del usuario

Digamos que usted esta desarrollando el próximo gran sitio web para compartir fotos, y quiere usar HTML5 para mostrar previsualizaciones de miniaturas de imágenes antes de que el usuario actual las suba. Basta con establecer su elemento input o zona de arrastre como se indicó anteriormente, y hacer una llamada a una funciónhandleFiles() como la siguiente.

function handleFiles(files) {  for (var i = 0; i < files.length; i++) {    var file = files[i];    var imageType = /image.*/;    if (!file.type.match(imageType)) {      continue;    }    var img = document.createElement("img");    img.classList.add("obj");    img.file = file;    preview.appendChild(img);    var reader = new FileReader();    reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);    reader.readAsDataURL(file);  }}

Aquí nuestro bucle recorre los archivos seleccionados por el usuario y mira el atributotype de cada archivo para ver si es una imagen (haciendo que una expresión regular coincida con la cadena de texto "image.*"). Para cada archivo que sea una imagen, creamos un nuevo elementoimg. Se puede usar CSS para establecer bordes bonitos, sombras, y especificar el tamaño de la imagen, el de manera que ni siquiera necesita hacerse aquí.

Cada imagen tiene la clase CSS "obj" añadida, para hacerla mas fácil buscarla en el árbol del DOM. Además añadimos un atributofile a cada imagen especificando elFichero para la imagen; esto nos permitira traer el hecho de subir las imágenes más tarde. Finalmente, usamosNode.appendChild() para añadir la nueva miniatura en el área de la previsualización de nuestro documento.

A continuación establecemos elFileReader para controlar la carga de la imagen de forma asíncrona y enlazarla con el elementoimg. Después de crear el nuevo objetoFileReader, configuramos su funciónonload, luego llamamos areadAsDataURL() para comenzar la operación de lectura en segundo plano. Cuando el contenido completo de la imagen ha sido cargado, se convierte adata: URL, el cuál es pasado al callbackonload. Nuestra implementación de esta rutina simplemente establece el atributosrc del elementoimg cargado, cuyo resultado es la imagen apareciendo en la miniatura en la pantalla del usuario.

Este ejemplo el objeto blob URLs para mostrar las miniaturas de las imágenes. Además, se muestra otra información del archivo incluyendo sus nombres y tamaños. Tú puedesver el ejemplo (tenga en cuenta que se requiere una versiónNghtly de Firefox del 23 de september 23 o mas reciente, o Firefox 4.0 beta 7).

El HTML que representa la interfaz es::

<form>  <input type="file" multiple accept="image/*" onchange="handleFiles(this.files)"></form><a href="#">Seleccione algunos archivos</a><div>  <p>¡No se han seleccionado archivos!</p></div>

Esto establece nuestro elemento<input> de nuestro, así como un enlace que invoca el selector de archivos, ya que mantenmos el input file oculto para prevenir mostrar un UI menos atractivo. Esto se explica anteriormente en al la secciónUsing hidden file input elements using the click() method, así como el métododoClick() que invoca el el selector de archivos.

El métodohandleFiles() es el siguiente:

function handleFiles(files) {  var d = document.getElementById("fileList");  if (!files.length) {    d.innerHTML = "<p>¡No se han seleccionado archivos!</p>";  } else {    var list = document.createElement("ul");    d.appendChild(list);    for (var i=0; i < files.length; i++) {      var li = document.createElement("li");      list.appendChild(li);      var img = document.createElement("img");      img.src = window.createBlobURL(files[i]);;      img.height = 60;      img.onload = function() {        window.revokeBlobURL(this.src);      }      li.appendChild(img);      var info = document.createElement("span");      info.innerHTML = files[i].name + ": " + files[i].size + " bytes";      li.appendChild(info);    }  }}

Esto comienza buscando la URL del<div> con la ID "fileList". Este es el bloque donde vamos a insertar la lista de archivos incluyendo las miniaturas.

Si el objetoFileList pasado ahandleFiles() esnull, simplemente establecemos el bloque inner HTML para mostrar "¡No se han seleccionado archivos!". En caso contrario, comenzamos a construir nuestra lista de archivos como sigue:

  1. Un nuevo elemento de lista desordenada (<ul> es creado.
  2. El nuevo elemento de la lista es insertado en el bloque<div> llamando a si métodoelement.appendChild().
  3. Para cadaFile en elFileList representadofiles:
    1. Se crea un nuevo elemento de lista (<li>) y lo inserta en la lista.
    2. Se crea un nuevo elemento imagen (<img>).
    3. Establece en la fuente de la imagen un nuevo blob URL representandoel archivo, usandowindow.createBlobURL() para crear el blob URL.
    4. Se establece el alto de la imagen en 60 pixels.
    5. Se configura el controlador para el evento load para liberar el blob URL, puesto que ya no es necesario una vez que la imagen ha sido cargada. Esto se hace llamando al métodowindow.revokeBlobURL(), pasando la cadena en el blob URL como se ha especificado paraimg.src.
    6. Se añade el nuevo elemento de la lista a la lista.

Ejemplo: Subiendo un archivo seleccionado por el usuario

Otra cosa que podrías querer hacer es dejar que el usuario suba el archivo o los archivos seleccionados (como las imagenes seleccionadas usando el ejemplo anterior) al servidor. Esto se puede hacer de forma asíncrona muy facilmente.

Creando las tareas de subida

Continuando con el código que contruye las miniaturas en el ejemplo anterior, hay que recordar que cada imagen en miniatura se encuentra en la clase CSS "obj", con el correspondienteFile adjunto en un attributofile. Vamos a seleccionar todas las imágenes que el usuario ha seleccionado facilmente para subirlas usandoDocument.querySelectorAll(), como sigue:

function sendFiles() {  var imgs = document.querySelectorAll(".obj");  for (var i = 0; i < imgs.length; i++) {    new FileUpload(imgs[i], imgs[i].file);  }}

La segunda línea crea un array, llamadoimgs, de todos los elementos en el documento con la clase CSS "obj". En nuestro caso, estos serán todas las miniaturas de las imágenes. Una vez que tenemos esa lista, of all the elements in the document with the CSS class "obj". In our case, these will be all the image thumbnails. Once we have that list, es trivial pasar por la lista, creando una nueva instancia deFileUpload por cada una. Subiendo el correspondiente archivo por cada uno de ellos.

Manipulando el proceso de carga de un archivo

La funciónFileUpload acepta dos entradas: un elemento de imagen y un archivo desde el que leer los datos de la imagen.

function FileUpload(img, file) {  this.ctrl = createThrobber(img);  var xhr = new XMLHttpRequest();  this.xhr = xhr;  var self = this;  this.xhr.upload.addEventListener("progress", function(e) {        if (e.lengthComputable) {          var percentage = Math.round((e.loaded * 100) / e.total);          self.ctrl.update(percentage);        }      }, false);  xhr.upload.addEventListener("load", function(e){          self.ctrl.update(100);          var canvas = self.ctrl.ctx.canvas;          canvas.parentNode.removeChild(canvas);      }, false);  xhr.open("POST", "https://demos.hacks.mozilla.org/paul/demos/resources/webservices/devnull.php");  xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');  xhr.sendAsBinary(file.getAsBinary());}

La funciónFileUpload() mostrada arriba crea un throbber, el cual es usado para mostrar la información del progreso, a continuación se crea unXMLHttpRequest para manejar la subida de los datos.

Antes de subir los datos de hecho, se toman varias medidas preparatorias:

  1. El listener del progreso de la carga delXMLHttpRequest's se configura para actualizar el throbber con una nueva información de porcentaje, por lo que a medida que progresa la carga, el throbber será actualizado en base a la última información.
  2. El evento "load" de la carga delXMLHttpRequest's se configura para actualizar el throbber con el 100% como la información de progreso (para asegurar que el indicador de progreso realmente alcanza el 100%, en caso de las peculiaridades de granularidad durante el proceso). Entoces se elimina el throbber, puesto que ya no es necesario. Esto causa que el throbber desaparezca una vez la carga está completa.
  3. La petición para cargar la imagen se inicia llamando al métodoXMLHttpRequest'sopen() para comenzar a generar una petición de tipo POST.
  4. El MIME type para la carga se establece llamando a la funcióndeXMLHttpRequestoverrideMimeType(). En este caso, estamos usando un MIME type genérico; usted puede o no puede necesitar establecer MIME type en absoluto, dependiendo de su necesidad.
  5. Finalmente, se llama a la funciónsendAsBinary() delXMLHttpRequest es llamada para subir el contenido del archivo.TEsto es necesario ser revisado, actualmete se está usando la rutina sincronizada en desuso getAsBinary() para extraer los datos del archivo..

Manipulación del proceso de carga para un archivo, de forma asíncrona

function fileUpload(file) {  // Please report improvements to: marco.buratto at tiscali.it  var fileName = file.name;  var fileSize = file.size;  var fileData = file.getAsBinary(); // works on TEXT data ONLY.  var boundary = "xxxxxxxxx";  var uri = "serverLogic.php";  var xhr = new XMLHttpRequest();  xhr.open("POST", uri, true);  xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary); // simulate a file MIME POST request.  xhr.setRequestHeader("Content-Length", fileSize);  xhr.onreadystatechange = function() {    if (xhr.readyState == 4) {      if ((xhr.status >= 200 && xhr.status <= 200) || xhr.status == 304) {        if (xhr.responseText != "") {          alert(xhr.responseText); // display response.        }      }    }  }  var body = "--" + boundary + "\r\n";  body += "Content-Disposition: form-data; name='fileId'; filename='" + fileName + "'\r\n";  body += "Content-Type: application/octet-stream\r\n\r\n";  body += fileData + "\r\n";  body += "--" + boundary + "--";  xhr.send(body);  return true;}

Esto necesita ser modificado para funcionar con datos binarios también.

Ver también

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp