gpt4 book ai didi

javascript - fileReader.readAsBinaryString 上传文件

转载 作者:IT王子 更新时间:2023-10-29 02:48:44 25 4
gpt4 key购买 nike

尝试使用 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)给了我

enter image description here

上传后显示相同的文件

enter image description here

所以它看起来像是某处的格式/编码问题,我尝试对原始二进制数据使用简单的 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;

这给了我

的输出

enter image description here

仍然不是原始文件的内容 =(

如何编码/加载/处理文件以避免编码问题,以便 HTTP 请求中接收的文件与上传前的文件相同。

一些其他可能有用的信息,如果我不使用 fileReader.readAsBinaryString() 而使用 fileObject.getAsBinary() 来获取二进制数据,它工作正常。但 getAsBinary 仅适用于 Firefox。我一直在 Firefox 和 Chrome 中测试这个,都在 Mac 上,在两者中得到相同的结果。后端上传由 NGINX Upload Module 处理,再次在 Mac 上运行。服务器和客户端在同一台机器上。我尝试上传的任何文件都会发生同样的事情,我只是选择了 PNG,因为它是最明显的例子。

最佳答案

(以下是迟到但完整的回答)

FileReader 方法支持


FileReader.readAsBinaryString() 已弃用。不要使用它! 它不再在 W3C File API working draft 中:

void abort();
void readAsArrayBuffer(Blob blob);
void readAsText(Blob blob, optional DOMString encoding);
void readAsDataURL(Blob blob);

注意:请注意 File是一种扩展 Blob结构。

Mozilla 仍然执行 readAsBinaryString()并在 MDN FileApi documentation 中对其进行了描述:

void abort();
void readAsArrayBuffer(in Blob blob); Requires Gecko 7.0
void readAsBinaryString(in Blob blob);
void readAsDataURL(in Blob file);
void readAsText(in Blob blob, [optional] in DOMString encoding);

背后的原因readAsBinaryString()我认为弃用如下:JavaScript 字符串的标准是 DOMString它只接受 UTF-8 字符,不接受随机二进制数据。所以不要使用 readAsBinaryString(),那根本不安全且不符合 ECMAScript。

我们知道 JavaScript 字符串不应该存储二进制数据 但 Mozilla 在某种程度上可以。我认为这很危险。 Blobtyped arrays ( ArrayBuffer 和尚未实现但不是必需的 StringView )是出于一个目的而发明的:允许使用纯二进制数据,不受 UTF-8 字符串限制。

XMLHttpRequest 上传支持


XMLHttpRequest.send() 具有以下调用选项:

void send();
void send(ArrayBuffer data);
void send(Blob data);
void send(Document data);
void send(DOMString? data);
void send(FormData data);

XMLHttpRequest.sendAsBinary() 具有以下调用选项:

void sendAsBinary(   in DOMString body );

sendAsBinary() 不是标准,Chrome 可能不支持。

解决方案


所以你有几个选择:

  1. send() FileReader.resultFileReader.readAsArrayBuffer ( fileObject ) .操作起来更复杂(您必须为其创建一个单独的 send()),但这是推荐的方法
  2. send() FileReader.resultFileReader.readAsDataURL( fileObject ) .它会产生无用的开销和压缩延迟,需要在服务器端执行解压缩步骤,但它很容易在 Javascript 中作为字符串进行操作。
  3. 非标准且sendAsBinary() FileReader.resultFileReader.readAsBinaryString( fileObject )

MDN指出:

The best way to send binary content (like in files upload) is using ArrayBuffers or Blobs in conjuncton with the send() method. However, if you want to send a stringifiable raw data, use the sendAsBinary() method instead, or the StringView (Non native) typed arrays superclass.

关于javascript - fileReader.readAsBinaryString 上传文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7431365/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com