代码之家  ›  专栏  ›  技术社区  ›  Nils Fett

从本地文件系统文件条目中使用createObjectURL会导致文件损坏

  •  0
  • Nils Fett  · 技术社区  · 8 年前

    我的应用程序是cordova应用程序。我尝试对平台浏览器执行以下操作。我知道所描述的问题不会在实际设备平台上出现。

    我尝试执行以下操作:

    1. 通过XMLHttpRequest下载图像文件
    2. 使用XMLHttpRequest响应中的blob通过createObjectURL显示图像
    3. 将文件写入本地文件系统(使用cordova插件文件使Firefox中的文件系统API可用)
    4. 使用本地文件系统中文件的blob通过createObjectURL显示图像

    我可以从保存的文件中创建一个blob,但之后图像就坏了。

    代码如下:

        var filesystem;
        var downloaddir;
        var filename = 'e44498f0b0964152632bd0c82342914b859c543e.jpeg'
        var downloadurl = 'http://adomain.com/public/content_images/'+filename;
    
    
        function download(){
          filesystem.root.getFile(
            '/ressources/'+filename, 
            { create: true, exclusive: false }, 
            function (fileEntry) {  
    
              var oReq = new XMLHttpRequest();
    
              oReq.open("GET", downloadurl, true);
              oReq.responseType = "blob";
              oReq.onload = function (oEvent) {
                var blob = oReq.response;
                if (blob) {         
                  fileEntry.createWriter(function (fileWriter) {                        
                    fileWriter.onwriteend = function (e) {
                      console.log(fileEntry.toURL());// Works in Chrome and Firefox, but file URIs cannot be used for security reasons. So image is not displayed if this RUL is used in image src attribute
                      console.log(window.URL.createObjectURL(blob));// work in chrome and firefox. This is what I like to have in the end but using a file.
    
                      // Now I want to use the file and transform it in a objectURL, this is where I struggle
                      fileEntry.file(function(file){
                        console.log(window.URL.createObjectURL(file));// works in chrome bot not in firefox. Firefox says :"TypeError: Argument 1 is not valid for any of the 1-argument overloads of URL.createObjectURL."
    
                        var readerBlob = new FileReader();                              
                        readerBlob.onload = function(event){                                    
                          var blob = new Blob([event.target.result], {type: 'image/jpg'});
                          console.log(window.URL.createObjectURL(blob));// blob uri will be created, but image is broken. Here I want to have a working objectURL that work for Chrome and Firefox           
                        };
                        readerBlob.readAsBinaryString(file);
                      });
    
                    };
                    fileWriter.onerror = function (e) {
                    };
                    fileWriter.write(blob);
                  });
    
                } else console.error('we didnt get an XHR response!');
              };
              oReq.send(null);
            }, 
            function (error) {
              console.log('error creating file');
              console.log(error);
            }
          );
        }
    
        document.addEventListener("deviceready", function(){
          window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
          window.requestFileSystem(window.TEMPORARY, 10 * 1024*1024, function (fs) {
            filesystem = fs;            
            filesystem.root.getDirectory(
              '/ressources/',
              {create:true}, 
              function(dirEntry){
                console.log('download dir created');
                downloaddir = dirEntry;
                download();
              },
              function(error){
              }
            );
          });
        }, false);
    
    1 回复  |  直到 4 年前
        1
  •  1
  •   Nils Fett    8 年前

    找到错误: 我必须用readAsArrayBuffer读取文件。这就成功了。因此,这里的工作代码可能会帮助某些人:

        var filesystem;
        var downloaddir;
        var filename = 'e44498f0b0964152632bd0c82342914b859c543e.jpeg'
        var downloadurl = 'http://adomain.com/public/content_images/'+filename;
    
    
        function download(){
          filesystem.root.getFile(
            '/ressources/'+filename, 
            { create: true, exclusive: false }, 
            function (fileEntry) {  
    
              var oReq = new XMLHttpRequest();
    
              oReq.open("GET", downloadurl, true);
              oReq.responseType = "blob";
              oReq.onload = function (oEvent) {
                var blob = oReq.response;
                if (blob) {         
                  fileEntry.createWriter(function (fileWriter) {                        
                    fileWriter.onwriteend = function (e) {
                      console.log(fileEntry.toURL());// Works in Chrome and Firefox, but file URIs cannot be used for security reasons. So image is not displayed if this RUL is used in image src attribute
                      console.log(window.URL.createObjectURL(blob));// works in chrome and firefox. This is what I like to have in the end but using a file.
    
                      // Now I want to use the file and transform it in a objectURL, this is where I struggle
                      fileEntry.file(function(file){
                        //console.log(window.URL.createObjectURL(file));// works in chrome bot not in firefox. Firefox says :"TypeError: Argument 1 is not valid for any of the 1-argument overloads of URL.createObjectURL."
    
                        var readerBlob = new FileReader();                              
                        readerBlob.onload = function(event){                                    
                          console.log(event.target.result);
    
                          var blob = new Blob([event.target.result], {type: 'image/jpg'});
                          console.log(window.URL.createObjectURL(blob));// This URL will work in Chrome and Firefox          
                        };
                        readerBlob.readAsArrayBuffer(file);
                      });
    
                    };
                    fileWriter.onerror = function (e) {
                    };
                    fileWriter.write(blob);
                  });
    
                } else console.error('we didnt get an XHR response!');
              };
              oReq.send(null);
            }, 
            function (error) {
              console.log('error creating file');
              console.log(error);
            }
          );
        }
    
        document.addEventListener("deviceready", function(){
          window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
          window.requestFileSystem(window.TEMPORARY, 10 * 1024*1024, function (fs) {
            filesystem = fs;            
            filesystem.root.getDirectory(
              '/ressources/',
              {create:true}, 
              function(dirEntry){
                console.log('download dir created');
                downloaddir = dirEntry;
                download();
              },
              function(error){
              }
            );
          });
        }, false);