1

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

4

3 回答 3

1

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

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

底线:Chrome 仅允许在用户批准的情况下进行持久文件系统存储。来自 Google 的更多信息:管理 HTML5 离线存储:持久存储

于 2013-08-23T00:10:17.410 回答
1

如果有人偶然发现这--unlimited-quota-for-files不再是一个有效的标志。但是,这里维护了一个当前铬标志的列表

--unlimited-storage我相信,这将是新的旗帜。

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

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

你得到了File Error没有,--allow-file-access-from-files因为如果允许浏览器在正常操作下访问这些文件,这将是一个安全问题,因此文件错误应该是类型SECURITY_ERR

以下链接中的信息是旧的,但策略类似于有问题的代码(现在改为 --unlimited-storage 的标志)。有关详细信息,请参阅这篇文章

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

navigator.webkitPersistentStorage.requestQuota(1024*1024, function(mB){
  window.requestFileSystem(PERSISTENT, mB, function(fs){
       //fs write/read, ect. code goes here. Or set a global variable to the value fs
       globalFS = fs; //to be accessed later in code, so you don't have to keep requesting.
  }, onError);
}, onError);
于 2014-03-12T22:09:46.590 回答
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>
于 2013-07-08T14:00:10.163 回答