2013-07-08 3 views
1

Я попытался написать немного кода для извлечения файла изображения (из Викисклада), сохранить его локально, а затем отобразить его. Здесь мой код:Использование LocalFileSystem для хранения и отображения изображений

<!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 не отображает сообщение об ошибке, поэтому я понятия не имею, почему она не работает. Любая подсказка?

Edit:

Я только что видел я на самом деле получить 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 или нет, что странно. Но я получаю файл Ошибка 2 без --allow-file-access-from-files

+0

Как насчет 'window.onload = функция() {xhr.send();};'? – Passerby

+0

Эта программа - просто эксперимент, чтобы увидеть, как все работает. –

ответ

0

Я добавил звонок window.webkitStorageInfo.requestQuota, и теперь он работает. Я не могу понять, почему это необходимо, поскольку я начал использовать Chrome с параметром --unlimited-quota-for-files.

Здесь рабочий код:

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

Меня все еще интересует объяснение, если вы знаете, почему опция -unlimited-quota-for-files не работает ... –

+0

Очень жаль, что на многих сайтах вы получите эту ошибку (в Chrome): «XMLHttpRequest не может загрузить .... Нет заголовок« Access-Control-Allow-Origin »присутствует на запрошенном ресурсе. Поэтому« Origin »...» не допускается ». – 10basetom

1

В ответ на вопросы о том, почему запуск с «--unlimited квотами для-файлов» не будет работать, я думаю, что вы путаете две разные вещи , Этот параметр просто удаляет ограничение квоты, он не автоматически предварительно одобряет сценарии, чтобы узурпировать пространство в песочнице без разрешения. Если вы использовали «временный» запрос файловой системы, то он выделил бы его без подсказки (см. Ссылку в конце моего ответа).

Но поскольку вы столкнулись с необходимостью вызова метода queryQuota(), Chrome не позволит распределять постоянное хранилище файловой системы без явного разрешения пользователя. Для этого есть несколько причин, но лучше всего обеспечить безопасность: именно, если Chrome должен был распределять постоянное хранилище файловой системы по требованию (без знания пользователя) любому скрипту, который его просил, тогда злонамеренный скрипт мог бы быстро заполнить пользовательский жесткий диск, сбой памяти Chrome из-за многих тысяч объектов и вызывают общий хаос. Такая уязвимость может также вызвать переполнение буфера, забивая такую ​​память.

В нижней строке: Chrome позволяет хранить постоянную файловую систему с одобрения пользователя. Больше от Google: Managing HTML5 Offline Storage:Persistent storage

+0

То, что вы говорите, имеет смысл. Тем не менее, мне интересно, почему требуются 2 шага (requestQuota и requestFileSystem), поскольку оба они являются обязательными и фактически образуют атомную операцию. Другим системам, таким как Cordova, удается избежать нестандартного шага requestQuota. Но я вижу вашу точку зрения. –

+0

Спасибо, Трарот. Поскольку метод requestQuota() также запрашивает у пользователя разрешение, он делает это отдельным шагом; требуется только в случае необходимости в зависимости от типа запрашиваемого хранилища. Кроме того, поскольку вы можете (я думаю) запросить больше квот «на лету», метод requestQuota() запрашивает пользователей каждый раз, чтобы убедиться, что с ними все в порядке, чтобы использовать больше локальных/ресурсов устройства. – PhilNicholas

1

Если кто-то наткнулся на него, --unlimited-quota-for-files больше не является действительным флагом. Однако есть list of current chromium flags maintained here.

--unlimited-storage был бы новый флаг для запуска, я считаю.

Переопределяет настройки квоты для каждого источника для неограниченного хранения для любых приложений/истоков. Это должно использоваться только для целей тестирования.

Я думаю, вам нужно было обновить запрос на квоту, потому что флаг ничего не менял (но я действительно не знаю, когда сам флаг был устаревшим). Поскольку он не работал так, как это было ранее (предполагая, что ваш код работал до этого, или вы получили его из учебника), я думаю, что браузер отказался от системы квот, когда переопределения не произошло, и увидел, что превышена квота с тем, что вы делали, тем самым исключив исключение.

Вы получили File Error без --allow-file-access-from-files потому, что это будет проблема безопасности, если браузер был разрешен доступ к этим файлам при нормальной работе, поэтому Ошиб.файл должен был быть типа SECURITY_ERR.

Информация в следующей ссылке устарела, но тактика похожа на код, о котором идет речь (вместо этого флаг -unlimited-storage вместо этого). See this article for more details.

Все сказанное. В фактическом приложении запрос Quota является обязательным, а решение OP на момент написания содержит правильный код. В настоящее время 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);