Usando archivos desde aplicaciones web

  • Enlace amigable (slug) de la revisión: Usando_archivos_desde_aplicaciones_web
  • Título de la revisión: Usando archivos desde aplicaciones web
  • Id de la revisión: 98072
  • Creada:
  • Creador: maedca
  • ¿Es la revisión actual? No
  • Comentario 942 words added, 848 words removed

Contenido de la revisión

{{ Traducción("inglés", "using_files_from_web_applications", "en") }}

{{ gecko_minversion_header("1.9.2") }}

 

Al usar la API de Archivos agregada al DOM en HTML5, ahora es posible que el contenido de una página web solicite al usuario que elija un archivo local para lugar leer el contenido de esos archivos. Esta selección puede hacerse tanto usando un elemento input de HTML o arrastrando y soltando el archivo.

 Seleccionar archivos usando HTML

 Seleccionar un solo archivo para usar con la API de archivo es simple:

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

Cuando el usuario selecciona un archivo, se  llama a la función handleFiles()  con un objeto FileList que contiene el objeto File representando el archivo seleccionado por el usuario.

Si desea permitir a el usuario seleccionar varios archivos, simplemente use el atributo multiple en el input element:

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

En este caso, la lista de archivos se pasa a la función handleFiles()contiene un File objeto por cada archivo que el usuario ha seleccionado.

{{ h2_gecko_minversion("Using hidden file input elements using the click() method", "2.0") }}

Starting in Gecko 2.0 {{ geckoRelease("2.0") }}, you can hide the admittedly ugly file {{ HTMLElement("input") }} element and present your own interface for opening the file picker and displaying which file or files the user has selected. You can do this by styling the input element with "display:none" and calling the click() method on the {{ HTMLElement("input") }} element.

Considere este código HTML:

<input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)">
<a href="#" id="fileSelect">Select some files</a> 

Tu método doClick() puede verse como esto:

var fileSelect = document.getElementById("fileSelect"),
  fileElem = document.getElementById("fileElem");

fileSelect.addEventListener("click", function (e) {
  if (fileElem) {
    fileElem.click();
  }
  e.preventDefault(); // prevent navigation to "#"
}, false);

Obiamente puedes darle estilo a el nuevo botón para abrir el selector de archivos como desee.

Dinámica de la adición de un detector de cambio

 Si tu campo de entrada fue creado con una librería de JavaScript como jQuery, necesitara usar {{ domxref("element.addEventListener()") }} para agregar el manejador de eventos de cambio, como este:

var inputElement = document.getElementById("inputField");
inputElement.addEventListener("change", handleFiles, false);

function handleFiles() {
  var fileList = this.files;

  /* now you can work with the file list */
}

 Note que en este caso, la función handleFiles() busca la lista de archivos en lugar de aceptar un parámetro, ya que los detectores de eventos añadidos de esta manera no pueden aceptar un parámetro de entrada.

 

{{ h1_gecko_minversion("Using object URLs", "2.0") }}

Gecko 2.0 {{ geckoRelease("2.0") }} introduces support for the DOM {{ domxref("window.URL.createObjectURL()") }} and {{ domxref("window.URL.revokeObjectURL()") }} methods. These let you create simple URL strings that can be used to reference any data that can be referred to using a DOM File object, including local files on the user's computer.

cuando tienes un objeto File te gustaría hacer referencia por URL desde HTML,puedes crear un objeto URL para que quede así :

var objectURL = window.URL.createObjectURL(fileObj);

The object URL is a string identifying the File object. Each time you call {{ domxref("window.URL.createObjectURL()") }}, a unique object URL is created, even if you've created an object URL for that file already. Each of these must be released. While they are released automatically when the document is unloaded, if your page uses them dynamically, you should release them explicitly by calling {{ domxref("window.URL.revokeObjectURL()") }}:

window.URL.revokeObjectURL(objectURL);

Selección de archivos usando arrastrar y soltar

 También puedes dejar que el usuario arrastre y suelte los archivos en la aplicación Web.

El primer paso es establecer una zona para soltar. Exactamente que parte de tu contenido aceptara soltar puede variar dependiendo de el diseño de tu aplicación, pero hacer un elemento que reciba eventos de soltar es fácil:

var dropbox;

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

 En este ejemplo, estamos girando el elemento con el ID "dropbox" en nuestra zona para soltar. Esto se hace mediante la adicción de escuchas para el dragenter, dragover, y drop events.

En realidad no necesitamos hacer nada con los eventos dragenter and dragover en nuestro caso, por lo que estas funciones son a la vez simples. Acaban de detener la propagación del evento y evitar que la acción predeterminada ocurra:

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

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

La verdadera magia pasa en la función drop():

function drop(e) {
  e.stopPropagation();
  e.preventDefault();

  var dt = e.dataTransfer;
  var files = dt.files;

  handleFiles(files);
}

Here, we retrieve the dataTransfer field from the event, then pull the file list out of it, passing that to handleFiles(). From this point on, handling the files is the same whether the user used the input element or drag and drop.

Obteniendo información de los archivos seleccionados

El objeto  FileList proporcionado por el DOM de las listas de todos los archivos seleccionados por el usuario, cada una se especifica como un objeto File. Tu puedes determinar cuantos archivos el usuario selecciona, al verificar el valor del atributo length:

var numFiles = files.length;

Individualmente los objetos File pueden ser recuperados simplemente accediendo a la lista como una matriz:

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

 Este bucle se repite en todos los archivos de la lista de archivos.

Hay tres atributos proporcionados por el objeto File que contienen información útil sobre el archivo.

name
El nombre de archivo como cadena de sólo lectura. Esto es sólo el nombre de el archivo y no incluye ninguna información de la ruta.
size
El tamaño del  archivo en bytes como de solo lectura entero de 64 bits.
type
El tipo MIME de el archivo como una cadena de sólo lectura, o "" si el tipo no puede ser determinado.

Ejemplo: Mostrando miniaturas de las imágenes seleccionadas por el usuario

Digamos que estás desarrollando el próximo gran sitio web para compartir fotos,y deseas usar HTML5 para mostrar vistas previas en miniaturas de las imágenes antes de que el usuario realmente suba los archivos. Simplemente basta con establecer el elemento de entrada o de soltar como se indicó anteriormente, y llamar una función, como la función handleFiles() de abajo.

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);
  }
}

Here our loop handling the user-selected files looks at each file's type attribute to see if it's an image file (by doing a regular expression match on the string "image.*"). For each file that is an image, we create a new img element. CSS can be used to establish any pretty borders, shadows, and to specify the size of the image, so that doesn't even need to be done here.

Cada imagen tiene la clase CSS "obj", añadida a la misma, para que sean fáciles de encontrar en el árbol DOM. También vamos a añadir un archivo atributo a cada imagen especificando el archivo de la imagen, o que nos permitirá buscar las imágenes para en realidad subirlas mas tarde. Por último se utilizamos {{ domxref("Node.appendChild()") }} para agregar la nueva miniatura para el área de previsualización de nuestro documento.

A continuación, se establece  FileReader para manejar de forma asincrónica la  carga de la  imagen y lo conecta con el elemento img.Después se crea  el  nuevo objeto FileReader, hemos creado la función load, a continuación llamamos readAsDataURL() para empezar la operación de lectura de fondo. cuando todo el contenido del archivo de imagen se carga, se convierten en una  data: URL, cada uno se pasa por  onload callback. Nuestra implementación de esta rutina se limita a establecer el atributo src del elemento img de la imagen cargada, lo que resulta en la imagen que aparece en la miniatura en la pantalla del usuario.

{{ h1_gecko_minversion("Example: Using object URLs to display images", "2.0") }}

En este ejemplo se utiliza el objeto URL para mostrar miniaturas de las imágenes. Además, se muestra la información de otro archivo con su nonbre y tamaño. Tu puedes ver el ejemplo vivo (nota se requiere  versión nocturna (nightly build) de Firefox de Noviembre 22 o posterior, o Firefox 4.0 beta 8).

Nota: Esta API existía en versiones beta de Firefox 4, pero cambio el 22 de noviembre, así que asegúrate que estas en una versión actual!

Escuchar
traducción del inglés al español
El código HTML que presenta la interfaz se parece a esto:

<input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)">
<a href="#" id="fileSelect">Select some files</a> 
<div id="fileList">
  <p>No files selected!</p>
</div>

Este establece nuestro archivo {{ HTMLElement("input") }} elemento, así como un enlace que invoca el selector de archivos , ya que mantener la entrada de archivo oculto para para evitar  que lo-menos-atractivo dela interfaz sea mostrado. Esto se explica más arriba en la sección  {{ anch("Using hidden file input elements using the click() method") }}, como es el método doClick() que invoca el selector de archivos.

El método siguiente handleFiles():

var fileSelect = document.getElementById("fileSelect"),
  fileElem = document.getElementById("fileElem"),
  fileList = document.getElementById("fileList");

fileSelect.addEventListener("click", function (e) {
  if (fileElem) {
    fileElem.click();
  }
  e.preventDefault(); // prevent navigation to "#"
}, false);

function handleFiles(files) {
  if (!files.length) {
    fileList.innerHTML = "<p>No files selected!</p>";
  }
  else {
    var list = document.createElement("ul");
    for (var i = 0; i < files.length; i++) {
      var li = document.createElement("li");
      list.appendChild(li);
      
      var img = document.createElement("img");
      img.src = window.URL.createObjectURL(files[i]);;
      img.height = 60;
      img.onload = function () {
        window.URL.revokeObjectURL(this.src);
      }
      li.appendChild(img);
      
      var info = document.createElement("span");
      info.innerHTML = files[i].name + ": " + files[i].size + " bytes";
      li.appendChild(info);
    }
    fileList.appendChild(list);
  }
}

Esto comienza por ir a buscar el {{ HTMLElement("div") }} con el ID "fileList". Este es el bloque en el que vamos a insertar la lista de archivos, incluyendo vistas en miniaturas.

Si el  objeto {{ domxref("FileList") }} handleFiles() es null, se establece dentro del código HTML interno del bloque para que no aparezca "No hay archivos seleccionados!". De lo contrario, empezamos a contruir nuestra lista de archivos, de la siguiente manera:

Una nueva lista desordenada elemento ({{ HTMLElement("ul") }} es creada.

  1. La nueva lista de elementos se inserta en el bloque  {{ HTMLElement("div") }} llamando a este método {{ domxref("element.appendChild()") }}.
  2. Para cada {{ domxref("File") }} en el {{ domxref("FileList") }} representado por files:
    1. Crear un nuevo elemento de la lista ({{ HTMLElement("li") }}) y se inserta en la lista.
    2. Crear un nuevo elemento imagen ({{ HTMLElement("img") }}).
    3. Ajuste de la imagen de origen a un nuevo objeto URL representando el archivo, usando {{ domxref("window.URL.createObjectURL()") }} para crear la blob URL.
    4. Ajuste la altura de la imagen a 60 píxeles.
    5. Establecer el manejador de el evento de carga de imagen para liberar el objeto URL, Set up the image's load event handler to release the object URL, puesto que ya no se necesita una vez que la imagen se ha cargado. esto se hace llamando a el método {{ domxref("window.URL.revokeObjectURL()") }} , pasando en el objeto URL la cadena como lo especifica img.src.
    6. Anexar el nuevo elemento lista a la lista.

Ejemplo: Cargando archivos seleccionado por el usuario (user-selected file)

Otra cosa que tu podrías querer hacer es permitir al usuario cargar  un archivo o archivos seleccionados (por ejemplo, las imagenes seleccionadas con el ejemplo previo) a un servidor. Esto puede hacerse asincrónicamente muy facil.

Creando las tareas de carga

Continuando con el código que genera las imágenes en miniatura en el ejemplo anterior, recordemos que cada imagen en la clase CSS "obj", con el correspondiente File adjunto en el atributo de el archivo. Esto nos permite fácilmente seleccionar todas las imagenes que el usuario ha escogido para ser cargadas con {{ domxref("Document.querySelectorAll()") }}, así:

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

En la linea 2 se crea una matriz, llamada imgs, de todos los elemtos in el documento con la clase CSS "obj". en nuestro caso, estas serán todas las miniaturas de las imágenes.Una vez que obtenemos esa lista, es trivial pasar por la lista, creando una nueva instancia FileUpload para cada uno. Cada uno de estos manejadores de carga el archivo correspondiente.

Manejadores de procesos de carga de un archivo

La función FileUpload acepta dos entradas: un elemento imagen y un archivo desde donde se leerán  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", "http://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ón FileUpload() muestra arriba crear un throbber, cada uno es usado para mostrar la información de progreso, a continuación se crea un XMLHttpRequest para manejar la carga de los datos.

Antes de transferir los datos actualmente, varios pasos preparatorios se tienen:

  1. El XMLHttpRequest's upload "progress" listener esta configurado para actualizar la información Throbber con nuevo porcentaje, de modo que a medida que avanza la carga, el Throbber sera actualizado basado en la ultima información.
  2. El XMLHttpRequest's upload "load" manejador de evento esta configurado para actualizar como un 100% como la información de progreso (para garantizar que el indicador de progreso realmente alcanza el 100%, en caso de peculiaridades y granulidades durante el proceso). A continuación se elimina el thobber, puesto que este no es necesario. Esto hace que el Thobber desaparezca una vez que la carga esta completa.
  3. La solicitud de carga de imagen se abre llamando el método XMLHttpRequest's open() para empezar a generar la POST solicitud.
  4. El tipo MIME para la carga esta configurada para llamar la función XMLHttpRequest function overrideMimeType(). En este caso, estamos usando un tipo MIME  genérico; puede o no ser necesario para configurar el tipo MIME para todo, dependiendo de su caso de uso.
  5. Finalmente la función XMLHttpRequest sendAsBinary() es llamada para cargar el contenido de el archivo. Esto necesita ser revisado; en la actualidad esta obsoleto la rutina para extraer datos desde archivos getAsBinary() síncrona.

Handling the upload process for a file, asynchronously

function fileUpload(file) {
  // Please report improvements to: marco.buratto at tiscali.it
  
  var fileName = file.name,
    fileSize = file.size,
    fileData = file.getAsBinary(), // works on TEXT data ONLY.
    boundary = "xxxxxxxxx",
    uri = "serverLogic.php",
    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;
}

This needs to be modified for working with binary data, too.

See also

{{ HTML5ArticleTOC() }}

Fuente de la revisión

<p>{{ Traducción("inglés", "using_files_from_web_applications", "en") }}</p>
<p>{{ gecko_minversion_header("1.9.2") }}</p>
<p> </p>
<p>Al usar la API de Archivos agregada al DOM en HTML5, ahora es posible que el contenido de una página web solicite al usuario que elija un archivo local para lugar leer el contenido de esos archivos. Esta selección puede hacerse tanto usando un elemento <code class="western"><a href="/en/DOM/HTMLInputElement" title="en/DOM/HTMLInputElement">input</a></code> de HTML o arrastrando y soltando el archivo.</p>
<h2> Seleccionar archivos usando HTML</h2>
<p> Seleccionar un solo archivo para usar con la API de archivo es simple:</p>
<pre><code>&lt;input type="file" id="input" onchange="handleFiles(this.files)"&gt;</code>
</pre>
<p>Cuando el usuario selecciona un archivo, se  llama a la función <code>handleFiles()</code>  con un objeto <a href="/en/DOM/FileList" title="en/DOM/FileList"><code>FileList</code></a> que contiene el objeto <a href="/en/DOM/File" title="en/DOM/File"><code>File </code></a>representando el archivo seleccionado por el usuario.</p>
<p>Si desea permitir a el usuario seleccionar varios archivos, simplemente use el atributo <code>multiple</code> en el <code>input</code> element:</p>
<pre><code>&lt;input type="file" id="input" multiple="true" onchange="handleFiles(this.files)"&gt;</code>
</pre>
<p>En este caso, la lista de archivos se pasa a la función <code>handleFiles()contiene </code><code>un</code> <a href="/en/DOM/File" title="en/DOM/File"><code>File</code></a> objeto por cada archivo que el usuario ha seleccionado.</p>
<p>{{ h2_gecko_minversion("Using hidden file input elements using the click() method", "2.0") }}</p>
<p>Starting in Gecko 2.0 {{ geckoRelease("2.0") }}, you can hide the admittedly ugly file {{ HTMLElement("input") }} element and present your own interface for opening the file picker and displaying which file or files the user has selected. You can do this by styling the input element with "display:none" and calling the <code>click()</code> method on the {{ HTMLElement("input") }} element.</p>
<p>Considere este código HTML:</p>
<pre class="deki-transform">&lt;input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)"&gt;
&lt;a href="#" id="fileSelect"&gt;Select some files&lt;/a&gt; 
</pre>
<p>Tu método <code>doClick()</code> puede verse como esto:</p>
<pre class="deki-transform">var fileSelect = document.getElementById("fileSelect"),
  fileElem = document.getElementById("fileElem");

fileSelect.addEventListener("click", function (e) {
  if (fileElem) {
    fileElem.click();
  }
  e.preventDefault(); // prevent navigation to "#"
}, false);
</pre>
<p>Obiamente puedes darle estilo a el nuevo botón para abrir el selector de archivos como desee.</p>
<h3>Dinámica de la adición de un detector de cambio</h3>
<p> Si tu campo de entrada fue creado con una librería de JavaScript como <a class=" external" href="http://www.jquery.com/">jQuery</a>, necesitara usar {{ domxref("element.addEventListener()") }} para agregar el manejador de eventos de cambio, como este:</p>
<pre class="deki-transform">var inputElement = document.getElementById("inputField");
inputElement.addEventListener("change", handleFiles, false);

function handleFiles() {
  var fileList = this.files;

  /* now you can work with the file list */
}
</pre>
<p> Note que en este caso, la función <code class="western">handleFiles()</code> busca la lista de archivos en lugar de aceptar un parámetro, ya que los detectores de eventos añadidos de esta manera no pueden aceptar un parámetro de entrada.</p>
<p> </p>
<p>{{ h1_gecko_minversion("Using object URLs", "2.0") }}</p>
<p>Gecko 2.0 {{ geckoRelease("2.0") }} introduces support for the DOM {{ domxref("window.URL.createObjectURL()") }} and {{ domxref("window.URL.revokeObjectURL()") }} methods. These let you create simple URL strings that can be used to reference any data that can be referred to using a DOM <a href="/en/DOM/File" title="en/DOM/File"><code>File</code></a> object, including local files on the user's computer.</p>
<p>cuando tienes un objeto<a href="/en/DOM/File" title="en/DOM/File"><code> File</code></a> te gustaría hacer referencia por URL desde HTML,puedes crear un objeto URL para que quede así :</p>
<pre>var objectURL = window.URL.createObjectURL(fileObj);
</pre>
<p>The object URL is a string identifying the <a href="/en/DOM/File" title="en/DOM/File"><code>File</code></a> object. Each time you call {{ domxref("window.URL.createObjectURL()") }}, a unique object URL is created, even if you've created an object URL for that file already. Each of these must be released. While they are released automatically when the document is unloaded, if your page uses them dynamically, you should release them explicitly by calling {{ domxref("window.URL.revokeObjectURL()") }}:</p>
<pre>window.URL.revokeObjectURL(objectURL);
</pre>
<h2>Selección de archivos usando arrastrar y soltar</h2>
<p> <span lang="es-ES">También puedes dejar que el usuario arrastre y suelte los archivos en la aplicación Web.</span></p>
<p>El primer paso es establecer una zona para soltar. Exactamente que parte de tu contenido aceptara soltar puede variar dependiendo de el diseño de tu aplicación, pero hacer un elemento que reciba eventos de soltar es fácil:</p>
<pre class="deki-transform">var dropbox;

dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
</pre>
<p> En este ejemplo, estamos girando el elemento con el ID "dropbox" en nuestra zona para soltar. Esto se hace mediante la adicción de escuchas para el <code class="western">dragenter</code>, <code class="western">dragover</code>, y <code class="western">drop</code> events.</p>
<p>En realidad no necesitamos hacer nada con los eventos <code class="western">dragenter</code> and <code class="western">dragover</code> en nuestro caso, por lo que estas funciones son a la vez simples. Acaban de detener la propagación del evento y evitar que la acción predeterminada ocurra:</p>
<pre class="deki-transform">function dragenter(e) {
  e.stopPropagation();
  e.preventDefault();
}

function dragover(e) {
  e.stopPropagation();
  e.preventDefault();
}
</pre>
<p>La verdadera magia pasa en la función <code class="western">drop()</code>:</p>
<pre class="deki-transform">function drop(e) {
  e.stopPropagation();
  e.preventDefault();

  var dt = e.dataTransfer;
  var files = dt.files;

  handleFiles(files);
}
</pre>
<p>Here, we retrieve the <code>dataTransfer</code> field from the event, then pull the file list out of it, passing that to <code>handleFiles()</code>. From this point on, handling the files is the same whether the user used the <code>input</code> element or drag and drop.</p>
<h2>Obteniendo información de los archivos seleccionados</h2>
<p>El objeto  <a href="/en/DOM/FileList" title="en/DOM/FileList"><code>FileList</code></a> proporcionado por el DOM de las listas de todos los archivos seleccionados por el usuario, cada una se especifica como un objeto<a href="/en/DOM/File" title="en/DOM/File"><code> File</code></a>. Tu puedes determinar cuantos archivos el usuario selecciona, al verificar el valor del atributo <code>length</code>:</p>
<pre>var numFiles = files.length;
</pre>
<p>Individualmente los objetos <a href="/en/DOM/File" title="en/DOM/File"><code>File</code></a> pueden ser recuperados simplemente accediendo a la lista como una matriz:</p>
<pre class="deki-transform">for (var i = 0; i &lt; files.length; i++) {
  var file = files[i];
  ..
}
</pre>
<p> Este bucle se repite en todos los archivos de la lista de archivos.</p>
<p>Hay tres atributos proporcionados por el objeto <a href="/en/DOM/File" title="en/DOM/File"><code>File</code></a> que contienen información útil sobre el archivo.</p>
<dl> <dt><code>name</code></dt> <dd>El nombre de archivo como cadena de sólo lectura. Esto es sólo el nombre de el archivo y no incluye ninguna información de la ruta.</dd> <dt><code>size</code></dt> <dd>El tamaño del  archivo en bytes como de solo lectura entero de 64 bits.</dd> <dt><code>type</code></dt> <dd>El tipo MIME de el archivo como una cadena de sólo lectura, o "" si el tipo no puede ser determinado.</dd>
</dl>
<h2>Ejemplo: Mostrando miniaturas de las imágenes seleccionadas por el usuario</h2>
<p>Digamos que estás desarrollando el próximo gran sitio web para compartir fotos,y deseas usar HTML5 para mostrar vistas previas en miniaturas de las imágenes antes de que el usuario realmente suba los archivos. Simplemente basta con establecer el elemento de entrada o de soltar como se indicó anteriormente, y llamar una función, como la función <code>handleFiles()</code> de abajo.</p>
<pre class="deki-transform">function handleFiles(files) {
  for (var i = 0; i &lt; 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);
  }
}
</pre>
<p>Here our loop handling the user-selected files looks at each file's type attribute to see if it's an image file (by doing a regular expression match on the string "image.*"). For each file that is an image, we create a new img element. CSS can be used to establish any pretty borders, shadows, and to specify the size of the image, so that doesn't even need to be done here.</p>
<p>Cada imagen tiene la clase CSS "obj", añadida a la misma, para que sean fáciles de encontrar en el árbol DOM. También vamos a añadir un archivo atributo a cada imagen especificando el archivo de la imagen, o que nos permitirá buscar las imágenes para en realidad subirlas mas tarde. Por último se utilizamos {{ domxref("Node.appendChild()") }} para agregar la nueva miniatura para el área de previsualización de nuestro documento.</p>
<p>A continuación, se establece  <a href="/en/DOM/FileReader" title="en/DOM/FileReader"><code>FileReader</code></a> para manejar de forma asincrónica la  carga de la  imagen y lo conecta con el elemento img.Después se crea  el  nuevo objeto <code>FileReader</code>, hemos creado la función <code>load</code>, a continuación llamamos <code>readAsDataURL()</code> para empezar la operación de lectura de fondo. cuando todo el contenido del archivo de imagen se carga, se convierten en una  <code>data:</code> URL, cada uno se pasa por  <code>onload</code> callback. Nuestra implementación de esta rutina se limita a establecer el atributo src del elemento img de la imagen cargada, lo que resulta en la imagen que aparece en la miniatura en la pantalla del usuario.</p>
<p>{{ h1_gecko_minversion("Example: Using object URLs to display images", "2.0") }}</p>
<p>En este ejemplo se utiliza el objeto URL para mostrar miniaturas de las imágenes. Además, se muestra la información de otro archivo con su nonbre y tamaño. Tu puedes <a href="/samples/domref/file-click-demo.html" title="https://developer.mozilla.org/samples/domref/file-click-demo.html">ver el ejemplo vivo </a>(nota se requiere  <a class=" external" href="http://nightly.mozilla.org/" title="http://nightly.mozilla.org/">versión nocturna (nightly build</a>) de Firefox de Noviembre 22 o posterior, o Firefox 4.0 beta 8).</p>
<div class="note"><strong>Nota:</strong> Esta API existía en versiones beta de Firefox 4, pero cambio el 22 de noviembre, así que asegúrate que estas en una versión actual!</div>
<p>Escuchar<br>
traducción del inglés al español<br>
El código HTML que presenta la interfaz se parece a esto:</p>
<pre class="deki-transform">&lt;input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)"&gt;
&lt;a href="#" id="fileSelect"&gt;Select some files&lt;/a&gt; 
&lt;div id="fileList"&gt;
  &lt;p&gt;No files selected!&lt;/p&gt;
&lt;/div&gt;
</pre>
<p>Este establece nuestro archivo {{ HTMLElement("input") }} elemento, así como un enlace que invoca el selector de archivos , ya que mantener la entrada de archivo oculto para para evitar  que lo-menos-atractivo dela interfaz sea mostrado. Esto se explica más arriba en la sección  {{ anch("Using hidden file input elements using the click() method") }}, como es el método <code>doClick()</code> que invoca el selector de archivos.</p>
<p>El método siguiente <code>handleFiles()</code>:</p>
<pre class="deki-transform">var fileSelect = document.getElementById("fileSelect"),
  fileElem = document.getElementById("fileElem"),
  fileList = document.getElementById("fileList");

fileSelect.addEventListener("click", function (e) {
  if (fileElem) {
    fileElem.click();
  }
  e.preventDefault(); // prevent navigation to "#"
}, false);

function handleFiles(files) {
  if (!files.length) {
    fileList.innerHTML = "&lt;p&gt;No files selected!&lt;/p&gt;";
  }
  else {
    var list = document.createElement("ul");
    for (var i = 0; i &lt; files.length; i++) {
      var li = document.createElement("li");
      list.appendChild(li);
      
      var img = document.createElement("img");
      img.src = window.URL.createObjectURL(files[i]);;
      img.height = 60;
      img.onload = function () {
        window.URL.revokeObjectURL(this.src);
      }
      li.appendChild(img);
      
      var info = document.createElement("span");
      info.innerHTML = files[i].name + ": " + files[i].size + " bytes";
      li.appendChild(info);
    }
    fileList.appendChild(list);
  }
}
</pre>
<p>Esto comienza por ir a buscar el {{ HTMLElement("div") }} con el ID "fileList". Este es el bloque en el que vamos a insertar la lista de archivos, incluyendo vistas en miniaturas.</p>
<p>Si el  objeto {{ domxref("FileList") }} <code>handleFiles()</code> es <code>null</code>, se establece dentro del código HTML interno del bloque para que no aparezca "No hay archivos seleccionados!". De lo contrario, empezamos a contruir nuestra lista de archivos, de la siguiente manera:</p>
<p>Una nueva lista desordenada elemento ({{ HTMLElement("ul") }} es creada.</p>
<ol> <li>La nueva lista de elementos se inserta en el bloque  {{ HTMLElement("div") }} llamando a este método {{ domxref("element.appendChild()") }}.</li> <li>Para cada {{ domxref("File") }} en el {{ domxref("FileList") }} representado por <code>files</code>: <ol> <li>Crear un nuevo elemento de la lista ({{ HTMLElement("li") }}) y se inserta en la lista.</li> <li>Crear un nuevo elemento imagen ({{ HTMLElement("img") }}).</li> <li>Ajuste de la imagen de origen a un nuevo objeto URL representando el archivo, usando {{ domxref("window.URL.createObjectURL()") }} para crear la blob URL.</li> <li>Ajuste la altura de la imagen a 60 píxeles.</li> <li>Establecer el manejador de el evento de carga de imagen para liberar el objeto URL, Set up the image's load event handler to release the object URL, puesto que ya no se necesita una vez que la imagen se ha cargado. esto se hace llamando a el método {{ domxref("window.URL.revokeObjectURL()") }} , pasando en el objeto URL la cadena como lo especifica <code>img.src</code>.</li> <li>Anexar el nuevo elemento lista a la lista.</li> </ol> </li>
</ol>
<h2>Ejemplo: Cargando archivos seleccionado por el usuario (user-selected file)</h2>
<p>Otra cosa que tu podrías querer hacer es permitir al usuario cargar  un archivo o archivos seleccionados (por ejemplo, las imagenes seleccionadas con el ejemplo previo) a un servidor. Esto puede hacerse asincrónicamente muy facil.</p>
<h3>Creando las tareas de carga</h3>
<p>Continuando con el código que genera las imágenes en miniatura en el ejemplo anterior, recordemos que cada imagen en la clase CSS "obj", con el correspondiente <a href="/en/DOM/File" title="en/DOM/File"><code>File</code></a> adjunto en el atributo de el archivo. Esto nos permite fácilmente seleccionar todas las imagenes que el usuario ha escogido para ser cargadas con {{ domxref("Document.querySelectorAll()") }}, así:</p>
<pre class="deki-transform">function sendFiles() {
  var imgs = document.querySelectorAll(".obj");
  
  for (var i = 0; i &lt; imgs.length; i++) {
    new FileUpload(imgs[i], imgs[i].file);
  }
}
</pre>
<p>En la linea 2 se crea una matriz, llamada <code>imgs</code>, de todos los elemtos in el documento con la clase CSS "obj". en nuestro caso, estas serán todas las miniaturas de las imágenes.Una vez que obtenemos esa lista, es trivial pasar por la lista, creando una nueva instancia <code>FileUpload</code> para cada uno. Cada uno de estos manejadores de carga el archivo correspondiente.</p>
<h3>Manejadores de procesos de carga de un archivo</h3>
<p>La función <code>FileUpload</code> acepta dos entradas: un elemento imagen y un archivo desde donde se leerán  los datos de la imagen</p>
<pre class="deki-transform">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", "http://demos.hacks.mozilla.org/paul/demos/resources/webservices/devnull.php");
  xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
  xhr.sendAsBinary(file.getAsBinary());
}
</pre>
<p>La función <code>FileUpload()</code> muestra arriba crear un throbber, cada uno es usado para mostrar la información de progreso, a continuación se crea un <a href="/en/XMLHttpRequest" title="en/XMLHttpRequest"><code>XMLHttpRequest</code></a> para manejar la carga de los datos.</p>
<p>Antes de transferir los datos actualmente, varios pasos preparatorios se tienen:</p>
<ol> <li>El <code>XMLHttpRequest</code>'s upload "progress" listener esta configurado para actualizar la información Throbber con nuevo porcentaje, de modo que a medida que avanza la carga, el Throbber sera actualizado basado en la ultima información.</li> <li>El <code>XMLHttpRequest</code>'s upload "load" manejador de evento esta configurado para actualizar como un 100% como la información de progreso (para garantizar que el indicador de progreso realmente alcanza el 100%, en caso de peculiaridades y granulidades durante el proceso). A continuación se elimina el thobber, puesto que este no es necesario. Esto hace que el Thobber desaparezca una vez que la carga esta completa.</li> <li>La solicitud de carga de imagen se abre llamando el método <code>XMLHttpRequest</code>'s <code>open()</code> para empezar a generar la POST solicitud.</li> <li>El tipo MIME para la carga esta configurada para llamar la función<code> XMLHttpRequest</code> function <code>overrideMimeType()</code>. En este caso, estamos usando un tipo MIME  genérico; puede o no ser necesario para configurar el tipo MIME para todo, dependiendo de su caso de uso.</li> <li>Finalmente la función <code>XMLHttpRequest</code> <code>sendAsBinary()</code> es llamada para cargar el contenido de el archivo. <em>Esto necesita ser revisado; en la actualidad esta obsoleto la rutina para extraer datos desde archivos getAsBinary() síncrona.</em></li>
</ol>
<h3>Handling the upload process for a file, asynchronously</h3>
<pre class="deki-transform">function fileUpload(file) {
  // Please report improvements to: marco.buratto at tiscali.it
  
  var fileName = file.name,
    fileSize = file.size,
    fileData = file.getAsBinary(), // works on TEXT data ONLY.
    boundary = "xxxxxxxxx",
    uri = "serverLogic.php",
    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 &gt;= 200 &amp;&amp; xhr.status &lt;= 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;
}
</pre>
<p><em>This needs to be modified for working with binary data, too.<br>
</em></p>
<h2>See also</h2>
<ul> <li><code><a href="/en/DOM/File" title="en/DOM/File">File</a><br> </code></li> <li><code><a href="/en/DOM/FileList" title="en/DOM/FileList">FileList</a><br> </code></li> <li><a href="/en/DOM/FileReader" title="en/DOM/FileReader"><code>FileReader</code></a></li> <li><a href="/En/XMLHttpRequest/Using_XMLHttpRequest" title="En/Using XMLHttpRequest">Using XMLHttpRequest</a></li> <li><a href="/en/XMLHttpRequest" title="en/XMLHttpRequest"><code>XMLHttpRequest</code></a></li>
</ul>
<p>{{ HTML5ArticleTOC() }}</p>
Revertir a esta revisión