Próba użycia fileReader.readAsBinaryString do przesłania pliku PNG na serwer przez AJAX, uproszczony kod (fileObject to obiekt zawierający informacje o moim pliku);
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);
Zbadanie kilku pierwszych wierszy pliku przed załadowaniem (używając VI) daje mi wyniki
Ten sam plik po przesłaniu pokazuje
Więc wygląda na to, że gdzieś występuje problem z formatowaniem / kodowaniem, próbowałem użyć prostej funkcji kodowania UTF8 na surowych danych binarnych
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;
)
Następnie w oryginalnym kodzie
//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;
co daje mi wynik
Nadal nie jest to, czym był surowy plik = (
Jak zakodować / załadować / przetworzyć plik, aby uniknąć problemów z kodowaniem, aby plik odbierany w żądaniu HTTP był taki sam, jak plik przed przesłaniem.
Kilka innych potencjalnie przydatnych informacji, jeśli zamiast używać fileReader.readAsBinaryString () używam fileObject.getAsBinary () do pobierania danych binarnych, działa dobrze. Ale getAsBinary działa tylko w przeglądarce Firefox. Testowałem to w przeglądarce Firefox i Chrome, oba na Macu, uzyskując ten sam wynik w obu. Przesyłanie do zaplecza jest obsługiwane przez moduł NGINX Upload , ponownie działający na komputerze Mac. Serwer i klient znajdują się na tym samym komputerze. To samo dzieje się z każdym plikiem, który próbuję przesłać, po prostu wybrałem PNG, ponieważ był to najbardziej oczywisty przykład.
<input type="file">
pola)