Tratando de usar fileReader.readAsBinaryString para cargar un archivo PNG al servidor a través de AJAX, código reducido (fileObject es el objeto que contiene información sobre mi archivo);
var fileReader = new FileReader();
fileReader.onload = function(e) {
var xmlHttpRequest = new XMLHttpRequest();
//Some AJAX-y stuff - callbacks, handlers etc.
xmlHttpRequest.open("POST", '/pushfile', true);
var dashes = '--';
var boundary = 'aperturephotoupload';
var crlf = "\r\n";
//Post with the correct MIME type (If the OS can identify one)
if ( fileObject.type == '' ){
filetype = 'application/octet-stream';
} else {
filetype = fileObject.type;
}
//Build a HTTP request to post the file
var data = dashes + boundary + crlf + "Content-Disposition: form-data;" + "name=\"file\";" + "filename=\"" + unescape(encodeURIComponent(fileObject.name)) + "\"" + crlf + "Content-Type: " + filetype + crlf + crlf + e.target.result + crlf + dashes + boundary + dashes;
xmlHttpRequest.setRequestHeader("Content-Type", "multipart/form-data;boundary=" + boundary);
//Send the binary data
xmlHttpRequest.send(data);
}
fileReader.readAsBinaryString(fileObject);
Examinar las primeras líneas de un archivo antes de cargarlo (usando VI) me da
El mismo archivo después de la carga muestra
Entonces parece un problema de formato / codificación en algún lugar, intenté usar una función de codificación UTF8 simple en los datos binarios sin procesar
function utf8encode(string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
)
Luego en el código original
//Build a HTTP request to post the file
var data = dashes + boundary + crlf + "Content-Disposition: form-data;" + "name=\"file\";" + "filename=\"" + unescape(encodeURIComponent(file.file.name)) + "\"" + crlf + "Content-Type: " + filetype + crlf + crlf + utf8encode(e.target.result) + crlf + dashes + boundary + dashes;
lo que me da la salida de
Todavía no es lo que era el archivo sin procesar = (
¿Cómo codifico / cargo / proceso el archivo para evitar los problemas de codificación, por lo que el archivo que se recibe en la solicitud HTTP es el mismo que el archivo antes de que se cargara?
Alguna otra información posiblemente útil, si en lugar de usar fileReader.readAsBinaryString () utilizo fileObject.getAsBinary () para obtener los datos binarios, funciona bien. Pero getAsBinary solo funciona en Firefox. He estado probando esto en Firefox y Chrome, ambos en Mac, obteniendo el mismo resultado en ambos. Las cargas de backend las gestiona el módulo de carga de NGINX , que se ejecuta nuevamente en Mac. El servidor y el cliente están en la misma máquina. Lo mismo sucede con cualquier archivo que intento cargar, simplemente elegí PNG porque era el ejemplo más obvio.
<input type="file">
campo normal )?