使用LocalFileSystem存储和显示图像

时间:2013-07-08 09:28:26

标签: javascript html5 html5-filesystem

我尝试编写一些代码来检索图像文件(来自Wikimedia Commons),将其存储在本地然后显示。这是我的代码:

<!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>

没有显示任何内容。 Chrome的控制台没有显示任何错误消息,所以我不知道为什么它不起作用。任何线索?

编辑:

我刚刚看到我实际上得到一个FileError,代码10,这意味着QUOTA_EXCEEDED_ERR,即使我使用这些参数启动我的Google Chrome:

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

实际上,无论有没有--unlimited-quota-for-files参数,我都会得到相同的错误,这很奇怪。但是我收到了没有--allow-file-access-from-files

的文件错误2

3 个答案:

答案 0 :(得分:1)

在回答您关于为什么使用“--unlimited-quota-for-files”无法启动的问题时,我认为您会混淆两件不同的事情。该参数只是删除了配额限制,它会自动预先批准脚本,以便在未经许可的情况下篡夺沙箱中的空间。如果您使用的是“临时”文件系统请求,那么它会在没有提示的情况下分配它(请参阅我的答案末尾的链接)。

但是,正如您在需要调用requestQuota()方法时遇到的那样,Chrome将不允许在没有明确用户权限的情况下分配持久性文件系统存储。这有几个原因,但安全性最好:即如果Chrome要按需要(没有用户知识)将持久文件系统存储分配给任何要求它的脚本,那么恶意脚本可以快速轻松填充用户的硬盘驱动器,由于成千上万的物体而导致Chrome内存崩溃,并造成一般混乱。这样的漏洞也可能通过锤击内存来触发缓冲区溢出。

结论:Chrome只允许用户批准持久存储文件系统。更多来自Google:Managing HTML5 Offline Storage:Persistent storage

答案 1 :(得分:1)

如果有人发现这一点,--unlimited-quota-for-files不再是有效标志。但是,有一个list of current chromium flags maintained here

我相信,

--unlimited-storage将成为新的旗帜。

  

将每个来源的配额设置覆盖为任何应用/来源的无限存储空间。这应该仅用于测试目的。

我认为您必须更新配额请求,因为该标志没有覆盖任何内容(但我实际上并不知道该标志本身何时被弃用)。因为它没有像以前那样工作(假设您的代码之前已经工作过,或者您从教程中获得了它)我认为浏览器在配置系统上没有发生,并且超出了配额与你正在做的事情,从而抛出异常。

你得到的File Error没有--allow-file-access-from-files,因为如果允许浏览器在正常操作下访问这些文件会出现安全问题,因此文件错误应该是类型{ {1}}。

以下链接中的信息是旧的,但该策略类似于相关代码(标志现在是--unlimited-storage)。See this article for more details

所有人都说,在实际应用中,配额请求是必须的,本文撰写时OP的解决方案包含正确的代码。目前,配额和fs请求的javascript如下所示:

SECURITY_ERR

答案 2 :(得分:0)

我添加了对window.webkitStorageInfo.requestQuota的调用,现在它可以正常工作了。我无法理解为什么有必要,因为我使用--unlimited-quota-for-files选项启动了Chrome。

这是工作代码:

<!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>