2011-09-23 17 views
5

Mi función javascript solo carga los archivos de texto correctamente. ¿Alguien puede ayudarme a descubrir cómo hacer que también acepte imágenes, etc.?Javascript no está cargando datos binarios

function fileUpload(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++) { 

    //Set vars 
    var file = files[i], 
    fileName = file.name, 
    fileSize = file.size, 
    fileData = file.getAsBinary(), 
    boundary = "xxxxxxxxx", 
    uri = "receive.php", 

    //Create file info HTML output 
    li = document.createElement("li"); 
    list.appendChild(li); 
    var info = document.createElement("span"); 
    info.innerHTML = file.name + ": " + file.size + " bytes"; 
    li.appendChild(info); 

    //Start sending file 
    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.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='upload'; filename='" + fileName + "'\r\n"; 
    body += "Content-Type: application/octet-stream\r\n\r\n"; 
    body += fileData + "\r\n"; 
    body += "--" + boundary + "--"; 

    xhr.send(body); 

} 
fileList.appendChild(list); 
return true; 
    } 
} 

Actualización: He encontrado la siguiente función en línea en http://code.google.com/p/html5uploader/ pero no puedo encontrar la manera de aplicarlo a mi función actual. ¿Es xhr.sendAsBinary lo único que cambió?

// Upload image files 
upload = function(file) { 

    // Firefox 3.6, Chrome 6, WebKit 
    if(window.FileReader) { 

     // Once the process of reading file 
     this.loadEnd = function() { 
      bin = reader.result;     
      xhr = new XMLHttpRequest(); 
      xhr.open('POST', targetPHP+'?up=true', true); 
      var boundary = 'xxxxxxxxx'; 
      var body = '--' + boundary + "\r\n"; 
      body += "Content-Disposition: form-data; name='upload'; filename='" + file.name + "'\r\n"; 
      body += "Content-Type: application/octet-stream\r\n\r\n"; 
      body += bin + "\r\n"; 
      body += '--' + boundary + '--';  
      xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary); 
      // Firefox 3.6 provides a feature sendAsBinary() 
      if(xhr.sendAsBinary != null) { 
       xhr.sendAsBinary(body); 
*snip* 
+0

¿cómo puede recuperar los archivos. Quiero decir que el parámetro de archivo debe proporcionarse en alguna parte. ¿Cómo haces eso? Necesito una pequeña explicación sobre este tema de carga de archivos a través de ajax. Cualquier ayuda será apreciada. – user1575229

+0

@ user1698985 No estoy seguro de lo que quieres decir, ¿te refieres a recuperarlo en el lado de PHP? En ese caso, puede encontrarlo en los datos POST. – natli

+0

recuperarlo del lado del servidor es otra discusión. Solo quiero encontrar la forma en que se selecciona el archivo en el cliente cargado en los datos de formularios y enviado a través de ajax. En Html5 es fácil. pero no entiendo cómo es en versiones anteriores de html. Traté de echar un vistazo al plugin ajaxform pero es difícil de entender cómo está recuperando los datos del archivo y enviándolos a través de ajax. Quiero entender todo el procedimiento, desde la selección del archivo hasta la gestión en jquery y enviarlo al servidor. – user1575229

Respuesta

2

No es un ejemplo del W3C de enviar una imagen GIF usando multipart/form-data en http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2:

 
Content-Type: multipart/form-data; boundary=AaB03x 

--AaB03x 
Content-Disposition: form-data; name="submit-name" 

Larry 
--AaB03x 
Content-Disposition: form-data; name="files" 
Content-Type: multipart/mixed; boundary=BbC04y 

--BbC04y 
Content-Disposition: file; filename="file1.txt" 
Content-Type: text/plain 

... contents of file1.txt ... 
--BbC04y 
Content-Disposition: file; filename="file2.gif" 
Content-Type: image/gif 
Content-Transfer-Encoding: binary 

...contents of file2.gif... 
--BbC04y-- 
--AaB03x-- 

Aviso la línea adicional Content-Transfer-Encoding: binary. Intenta agregar eso.

EDIT: Try base 64 codifica los datos del archivo utilizando the Base64 jQuery plugin:

var body = "--" + boundary + "\r\n"; 
    body += "Content-Disposition: form-data; name='upload'; filename='" + fileName + "'\r\n"; 
    body += "Content-Type: application/octet-stream\r\n"; 
    body += "Content-Transfer-Encoding: base64\r\n\r\n"; 
    body += $.base64Encode(fileData) + "\r\n"; 
    body += "--" + boundary + "--"; 
+0

Lamentablemente eso no cambió nada. Los archivos de texto aún se cargaron correctamente pero las imágenes no. Las imágenes terminan en el servidor dañado y son aproximadamente el doble de su tamaño de archivo normal. Sin embargo, encontré una función en línea que hace lo que quiero, pero como soy nuevo en JavaScript, no sé cómo implementarlo en mi propia función. (Consulte la pregunta actualizada) Debido a mi inexperiencia, tampoco entiendo su pregunta, ¿por qué debería ser body.length? – natli

+0

@natli: [Como Firefox es aparentemente el único navegador que admite 'sendAsBinary()' nativamente] (http://stackoverflow.com/q/4236153/196844), parece que usan el archivo 'sendAsBinary() de FF incorporado 'método, pero en Chrome y Safari, implementan una solución alternativa (solo una suposición, sin embargo). En cualquier caso, quizás el binario debería estar codificado con base64 primero. Luego configure 'Content-Transfer-Encoding: base64'. En cuanto a 'Content-Length', este es uno de los encabezados que no se puede establecer con el método' setRequestHeader() '(http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader-method). Entonces, no te preocupes por eso. –

+0

@natli: Actualicé mi respuesta. –