尝试使用 fileReader.readAsBinaryString 通过 AJAX 将 PNG 文件上传到服务器,精简代码(fileObject 是包含我的文件信息的对象);
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);
在上传之前检查文件的前几行(使用 VI)给了我
上传后显示同一个文件
所以它看起来像是某个地方的格式/编码问题,我尝试在原始二进制数据上使用简单的 UTF8 编码函数
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;
)
然后在原代码中
//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;
这给了我输出
仍然不是原始文件是什么 =(
我如何编码/加载/处理文件以避免编码问题,因此 HTTP 请求中接收的文件与上传之前的文件相同。
其他一些可能有用的信息,如果不是使用 fileReader.readAsBinaryString() 我使用 fileObject.getAsBinary() 来获取二进制数据,它工作正常。但是 getAsBinary 仅适用于 Firefox。我一直在 Mac 上的 Firefox 和 Chrome 中对此进行测试,两者都得到了相同的结果。后端上传由NGINX 上传module处理,再次在 Mac 上运行。服务器和客户端在同一台机器上。我尝试上传的任何文件都会发生同样的事情,我只是选择了 PNG,因为它是最明显的例子。