2012-08-08 20 views
10

No recibo la carga de archivos adjuntos para que funcione el navegador.¿Cómo subir un archivo (archivo adjunto) desde el navegador?

Algunas pistas son here, otras there. The docs son bastante buenos, pero no puedo traducir eso a una carga de AJAX.

Busco un ejemplo muy sencillo de HTML/JavaScript (con o w/o jQuery) de cómo cargar un archivo desde el navegador (relativamente moderno) a la db sin haciendo uso de jquery.couch.app .js envoltura o cosas. Cuanto más simple es el besser.

Cualquier ayuda apreciada.

Respuesta

18

Bien, aquí está su implementación de carga de archivos de JavaScript puro.

El algoritmo básico es la siguiente:

  1. obtener el archivo desde el elemento de entrada de archivo
  2. Obtener el nombre de archivo y el tipo de objeto fichero
  3. Obtener el último documento de revisión del documento que desee adjuntar el archivo a
  4. adjuntar el archivo para documentar el uso de la revisión descabellada

el HTML parte básicamente consiste en una forma simple con dos elementos, una entrada de tipo file y un botón del tipo submit.

<form action="/" method="post" name="upload"> 
    <input type="file" name="file" /> 
    <button type="submit" name="submit">Upload</button> 
</form> 

Ahora a la parte de JavaScript.

window.onload = function() { 
    var app = function() { 
     var baseUrl = 'http://127.0.0.1:5984/playground/'; 
     var fileInput = document.forms['upload'].elements['file']; 
     document.forms['upload'].onsubmit = function() { 
      uploadFile('foo', fileInput.files[0]); 
      return false; 
     }; 

     var uploadFile = function(docName, file) { 
      var name = encodeURIComponent(file.name), 
      type = file.type, 
      fileReader = new FileReader(), 
      getRequest = new XMLHttpRequest(), 
      putRequest = new XMLHttpRequest(); 

      getRequest.open('GET', baseUrl + encodeURIComponent(docName), 
       true); 
      getRequest.send(); 
      getRequest.onreadystatechange = function(response) { 
       if (getRequest.readyState == 4 && getRequest.status == 200) { 
        var doc = JSON.parse(getRequest.responseText); 
        putRequest.open('PUT', baseUrl + 
         encodeURIComponent(docName) + '/' + 
         name + '?rev=' + doc._rev, true); 
        putRequest.setRequestHeader('Content-Type', type); 
        fileReader.readAsArrayBuffer(file); 
        fileReader.onload = function (readerEvent) { 
         putRequest.send(readerEvent.target.result); 
        }; 
        putRequest.onreadystatechange = function(response) { 
         if (putRequest.readyState == 4) { 
          console.log(putRequest); 
         } 
        }; 
       } 
      }; 
     }; 
    }; 
    app(); 
}; 

Básicamente, interceptar el evento submit de la forma por la unión de mi propia función para el evento de la forma onsubmit y volviendo falsa.

En ese controlador de eventos llamo a mi función principal con dos parámetros. El primero es el nombre del documento y el segundo es el archivo para cargar.

En mi función uploadFile() establezco el nombre del archivo, el tipo de archivo y tomo algunas instancias. La primera solicitud HTTP es una solicitud GET para obtener la revisión actual del documento. Si esa solicitud tiene éxito, preparo la solicitud PUT (la solicitud de carga real) configurando la revisión obtenida previamente, el tipo de contenido apropiado y luego convierto el archivo a un ArrayBuffer. Una vez hecho esto, simplemente envío la solicitud HTTP que acabo de preparar y luego me relajo.

El esquema de carga de archivos adjuntos independiente tiene el siguiente aspecto:

PUT host/database/document/filename?revision=latest-revision 

Por supuesto utilizando el tipo de contenido adecuado en el encabezado de la solicitud HTTP.

Nota: Soy consciente de que no estoy haciendo uso de la programación defensiva aquí en absoluto, lo hice deliberadamente por brevedad.

+0

Gran ejemplo y explicación. ¡Esto es exactamente lo que estaba buscando! – Jlange

+1

Tenga en cuenta que jQuery no se utiliza aquí porque no admite objetos ArrayBuffer, que es lo que devuelve readerEvent.target.result.Esto me llevó unas horas averiguarlo, así que imaginé que lo escribiría para otros. – samoz

+1

Muy buena respuesta, pero usar una variable local llamada 'document' es IMO, un no-no en el lado del cliente de JavaScript. Simplemente diciendo ... –

Cuestiones relacionadas