Search code examples
javascripthtmlhtml5-filesystem

Using LocalFileSystem to store and display images


I tried to write a bit of code to retrieve an image file (from Wikimedia Commons), store it locally and then display it. Here my code:

<!DOCTYPE html> 
<html> 
<head>
<script>

window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;

function onError(e) {
  console.log('Error', e);
}

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://upload.wikimedia.org/wikipedia/fr/2/26/10_francs_Mathieu_1987_F365-28_revers.jpg', true);
xhr.responseType = 'blob';

xhr.onload = function(e) {

window.requestFileSystem(PERSISTENT, 1024 * 1024, function(fs) {alert(fs.root.name);}, onError);

  window.requestFileSystem(PERSISTENT, 1024 * 1024, function(fs) {
    fs.root.getFile('image.jpg', {create: true}, function(fileEntry) {
      fileEntry.createWriter(function(writer) {

        writer.onwrite = function(e) {};
        writer.onerror = function(e) {};

        var blob = new Blob([xhr.response], {type: 'image/jpeg'});

        writer.write(blob);

      }, onError);
    }, onError);
  }, onError);

  window.requestFileSystem(PERSISTENT, 1024 * 1024, function(fs) {
    fs.root.getFile('image.jpg', {create: false}, function(fileEntry) {
        fileEntry.file(function(file) {
            var reader = new FileReader();
            reader.onloadend = function(event) {
                var img = document.createElement("img");
                img.src = event.target.result;

                document.body.parentNode.insertBefore(img, document.body.nextSibling);
            };
            reader.readAsDataURL(file);
        }, onError);
    }, onError);
  }, onError);

};

xhr.send();
</script>
</head> 
<body>

</body>
</html>

Nothing is displayed. Chrome's console doesn't display any error message, so I have no idea why it's not working. Any clue?

Edit :

I have just seen I actually get a FileError, code 10, which means QUOTA_EXCEEDED_ERR, even if I start my Google Chrome with these parameters:

"C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --unlimited-quota-for-files

Actually, I get the same error with or without the --unlimited-quota-for-files parameter, which is weird. But I get a File Error 2 without --allow-file-access-from-files


Solution

  • I added a call to window.webkitStorageInfo.requestQuota, and now it works. I can't get why it is necessary, as I started Chrome with the --unlimited-quota-for-files option.

    Here the working code:

    <!DOCTYPE html> 
    <html> 
    <head>
    <script>
    
    window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;
    
    function onError(e) {
      console.log('Error', e);
    }
    
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://upload.wikimedia.org/wikipedia/fr/2/26/10_francs_Mathieu_1987_F365-28_revers.jpg', true);
    xhr.responseType = 'blob';
    
    xhr.onload = function(e) {
      window.webkitStorageInfo.requestQuota(PERSISTENT, 1024*1024, function(grantedBytes) {
      window.requestFileSystem(PERSISTENT, 1024 * 1024, function(fs) {
        fs.root.getFile('image.jpg', {create: true}, function(fileEntry) {
          fileEntry.createWriter(function(writer) {
    
            writer.onwrite = function(e) {};
            writer.onerror = function(e) {};
    
            var blob = new Blob([xhr.response], {type: 'image/jpeg'});
    
            writer.write(blob);
    
          }, function(e) {
      console.log('Error', e);
    });
        }, function(e) {
      console.log('Error', e);
    });
      }, function(e) {
      console.log('Error', e);
    });
    }, function(e) {
      console.log('Error', e);
    });
    
      window.requestFileSystem(PERSISTENT, 1024 * 1024, function(fs) {
        fs.root.getFile('image.jpg', {create: false}, function(fileEntry) {
            fileEntry.file(function(file) {
                var reader = new FileReader();
                reader.onloadend = function(event) {
                    var img = document.createElement("img");
                    img.src = event.target.result;
    
                    document.body.parentNode.insertBefore(img, document.body.nextSibling);
                };
                reader.readAsDataURL(file);
            }, function(e) {
      console.log('Error', e);
    });
        }, function(e) {
      console.log('Error', e);
    });
      }, function(e) {
      console.log('Error', e);
    });
    
    };
    
    xhr.send();
    </script>
    </head> 
    <body>
    
    </body>
    </html>