【问题标题】:JavaScript readAsBinaryString Function on E11E11 上的 JavaScript readAsBinaryString 函数
【发布时间】:2015-07-13 18:52:23
【问题描述】:

在此页面http://www.html5rocks.com/en/tutorials/file/dndfiles/ 中,如果您向下滚动到示例“示例:切片文件。试试看!”您将看到使用 readAsBinaryString API 来读取本地文件的字节数。

我看到 IE(我的情况是 IE11)不支持 readAsBinaryString

即使HTML5 File API read as text and binary 帖子中提到的这段代码在 IE11 中的 readAsBinaryString 处也会中断。

我在堆栈溢出中看到了一些帖子,它建议使用 ReadAsArrayBuffer()。但它也不起作用。它返回未定义。

我的问题是,如果我必须在 IE11 上运行它,有哪些选项?是否可以编写另一个兼容 IE 的 JS 函数来执行 readAsBinaryString() 的 JOB。

【问题讨论】:

    标签: javascript html internet-explorer


    【解决方案1】:

    我将@Jack 的回答与我的评论结合起来,展示了一个完整的工作示例。

    <head>部分我添加了这个脚本来在IE11中添加FileReader.readAsBinaryString函数

    if (FileReader.prototype.readAsBinaryString === undefined) {
        FileReader.prototype.readAsBinaryString = function (fileData) {
            var binary = "";
            var pt = this;
            var reader = new FileReader();
            reader.onload = function (e) {
                var bytes = new Uint8Array(reader.result);
                var length = bytes.byteLength;
                for (var i = 0; i < length; i++) {
                    binary += String.fromCharCode(bytes[i]);
                }
                //pt.result  - readonly so assign content to another property
                pt.content = binary;
                pt.onload(); // thanks to @Denis comment
            }
            reader.readAsArrayBuffer(fileData);
        }
    }
    

    然后我需要稍微修改我原来的脚本代码,因为target.result 在使用这个回退函数时没有任何价值。

    var reader = new FileReader();
    reader.onload = function (e) {
        // ADDED CODE
        if (!e) {
            var data = reader.content;
        }
        else {
            var data = e.target.result;
        }
    
        // business code
    };
    reader.readAsBinaryString(myFile);
    

    【讨论】:

    • $(pt).trigger('onload');是jQuery的触发方式吗?如何在没有 jQuery 的情况下调度此事件?
    • Jack + Naigel = 拯救了我的一天
    • @Denis 添加了您的建议,它是唯一需要 jQuery 的代码行,并且很容易使用 vanilla JS 进行更改。
    • @NachPD 很高兴帮助别人,我已经在这一点上浪费了几个小时,让我们让他们变得有价值 ;)
    • 为什么不总是使用e.target.result!e 是真的吗?
    【解决方案2】:

    这是我的解决方案。

    var reader = new FileReader();
    reader.readAsBinaryString(fileData);
    reader.onload = function(e) {
      if (reader.result) reader.content = reader.result;
      var base64Data = btoa(reader.content);
      //...
    }
    //extend FileReader
    if (!FileReader.prototype.readAsBinaryString) {
        FileReader.prototype.readAsBinaryString = function (fileData) {
           var binary = "";
           var pt = this;
           var reader = new FileReader();      
           reader.onload = function (e) {
               var bytes = new Uint8Array(reader.result);
               var length = bytes.byteLength;
               for (var i = 0; i < length; i++) {
                   binary += String.fromCharCode(bytes[i]);
               }
            //pt.result  - readonly so assign binary
            pt.content = binary;
            $(pt).trigger('onload');
        }
        reader.readAsArrayBuffer(fileData);
        }
    }
    

    【讨论】:

    • 在我使用FileReader的主要代码中:var reader = new FileReader(); reader.onload = function (e) { var data = e.target.result; ..CODE HERE.. }; reader.readAsBinaryString(myFile)。我需要这样更改reader.onloadreader.onload = function (e) { if (!e) {var data = reader.content;} else {var data = e.target.result; } ..CODE HERE.. };
    • @Naigel 评论对他写的更改很有帮助。结合 Jacks 代码和 Naigels 对我有用
    • $(pt).trigger('onload');是jQuery的触发方式吗?如何在没有 jQuery 的情况下调度此事件?
    【解决方案3】:

    FileReader.readAsBinaryString 是一个非标准函数,已被弃用。

    应该改用FileReader.readAsArrayBuffer

    MDN

    【讨论】:

      【解决方案4】:

      对于 IE 11,您可以使用这个 XHR 技巧:

      function blobToBinaryStringIE11(blob) {
          var blobURL = URL.createObjectURL(blob);
          var xhr = new XMLHttpRequest;
          xhr.open("get", blobURL);
          xhr.overrideMimeType("text/plain; charset=x-user-defined");
          xhr.onload = function () {
              var binary = xhr.response;
              // do stuff
          };
          xhr.send();
      }
      

      它比 Uint8Array + fromCharCode 路由快 20 倍,与 readAsBinaryString 一样快。

      【讨论】:

        【解决方案5】:

        替换

        reader.readAsBinaryString(blob);
        

        与:

        reader.readAsText(blob);
        

        它在跨浏览器中运行良好。

        【讨论】:

        • 这个有问题。由于浏览器认为它的文本而不是二进制它可能会导致错误,例如在 Firefox 中我收到无效字符错误。
        【解决方案6】:

        我对这里的答案有一些疑问,最后做了一些细微的改动。

        我的解决方案不是分配给 pt.content,而是向原型的 onload 发送一个自定义对象,接收者可以专门查找,我将此属性命名为 msieContent,这样它会非常具体。

        我还使用了其他公认的答案来以更强大的方式将 Uint8Array 转换为字符串,您可以在此处查看完整的详细信息: https://stackoverflow.com/a/12713326/213050

        Polyfill

        if (FileReader.prototype.readAsBinaryString === undefined) {
            // https://stackoverflow.com/a/12713326/213050
            function Uint8ToString(u8a: Uint8Array) {
                const CHUNK_SZ = 0x8000;
                let c = [];
                for (let i = 0; i < u8a.length; i += CHUNK_SZ) {
                    c.push(String.fromCharCode.apply(null, u8a.subarray(i, i + CHUNK_SZ)));
                }
                return c.join('');
            }
            FileReader.prototype.readAsBinaryString = function (fileData) {
                const reader = new FileReader();
                reader.onload = () => this.onload({
                    msieContent: Uint8ToString(new Uint8Array(<any>reader.result))
                });
                reader.readAsArrayBuffer(fileData);
            }
        }
        

        用法

        private _handleTextFile(file: File) {
            const reader = new FileReader();
        
            reader.onload = (e) => {
                // support for msie, see polyfills.ts
                const readResult: string = (<any>e).msieContent || <string>e.target.result;
        
            };
        
            reader.readAsBinaryString(file);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-06
          • 1970-01-01
          • 2019-02-09
          • 2016-03-06
          • 2020-12-04
          • 1970-01-01
          相关资源
          最近更新 更多