Я пытаюсь прочитать файл JSON внутри www with Cordova.
Я пробую множество систем, тестов и решений, которые, однако, терпят неудачу одна за другой .
Простейшая концепция (выборка)
Результат: локальная работа. В приложении: «получить ошибку», если используется cordova.file.dataDirectory
. Результат: «NetworkError при попытке извлечь ресурс».
document.addEventListener('click', test ,true);
document.addEventListener('touchstart', test ,true);
function test(){
alert("try fetch");
const jsonFile = "./geoita.json"; // fail on app
const jsonFile = cordova.file.dataDirectory+"geoita.json"; //security
var headers = new Headers({
"Content-Type": "text/plain",
"Accept": "text/plain"
});
window.fetch( jsonFile, headers )
.then( resp => resp.json() )
.then( json => {
console.log(json);
alert("Result: "+json);
document.body.innerHTML=JSON.stringify(json);
})
.catch(function(error) {
console.log('ERROR: ' + error.message);
alert('ERROR: ' + error.message);
});
};
ТЕСТ 2 (запрос)
Результат: защита файла. Вы не можете получить файл, поэтому вы не можете прочитать его.
var req = new XMLHttpRequest();
req.onreadystatechange = () =>
{
console.log("try in api style...");
if (req.readyState==4 && req.status==200)
{
console.log("reading...");
let json = JSON.parse(req.responseText);
console.log(json);
}
else {
console.log("try in api style - error: "+req.readyState);
}
}
req.open("GET",(cordova.file.dataDirectory+"geoita.json"),true);
req.send();
ТЕСТ 3 (следуйте официальному руководству)
Результат: файл не найден или ошибка кодирования.
const filePath = cordova.file.applicationDirectory+"geoita.json"; //return error code 5 ENCODING_ERR
//const filePath = "www/geoita.json"; // return error 1 NOT_FOUND_ERR
//const filePath ="geoita.json";
//const filePath = cordova.file.applicationDirectory+"geoita.txt"; // not changed
window.resolveLocalFileSystemURL( filePath ,
fileEntry => {
console.log("file object ready");
fileEntry.file(
File => {
console.log("content: ",File);
var reader = new FileReader();
reader.onloadend = function(evt)
{
console.log("read success",evt.target.result);
};
reader.readAsText(File);
});
}, error => console.error(error) );
Я продолжаю делать много тестов, но я не понимаю, что происходит не так. Я не понимаю, почему так трудно читать локальный файл в www folder Cordova.
Как я могу это сделать?
Обновление
Более 32 после тестов решение оказалось неправильным.
К сожалению, я только что понял, что он не записывает файл из www folder. Что вы можете сделать, это "создать файл из переменной, преобразовать его в постоянный файл и затем перечитайте его. Он по-прежнему не читается так, как я хотел.
То, что произошло во время теста, является просто результатом предыдущих тестов, в которых я "скопировал файл в переменную вручную", поэтому у меня было неосознанно сохранил его и впоследствии восстановил, как если бы он читал локальный файл (который, конечно, был идентичен)
К сожалению, я до сих пор не могу найти решение для чтения файла. Если вам известно об этом , напишите!
Для этого примера у нас есть 2 типа данных.
1) - это простая переменная в сообщении json;
2) Это локальный файл в директории www (потом создаем файл ханом d что вы можете восстановить ... текст с ложными json данными, похожими на данные в 1)
шаг 00
добавить cordova-file-plugin в ваш проект
https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/index.html
Шаг 01
В конфигурации. xml
<platform name="android">
<preference name="AndroidPersistentFileLocation" value="Compatibility" />
<preference name="AndroidExtraFilesystems" value="assets,root, files, cache, sdcard, cache-external, files-external" />
</platform>
<platform name="ios">
<preference name="iosPersistentFileLocation" value="Compatibility" />
<preference name="iosExtraFilesystems" value="assets,root, files,cache, sdcard, cache-external, files-external" />
</platform>
Потенциально также может потребоваться ввести:
<access origin="*" /> <access origin="cdvfile://*"/> <access origin="file:///*"/>
Шаг 02
Теперь, когда приложение готово, пример:
if('cordova' in window)
{
document.addEventListener('deviceready', mytest);
// console.log('device');
}
else
{
document.addEventListener('DOMContentLoaded', mytest);
// console.log('web device');
}
в альтернативном соединении с событием:
document.addEventListener('click', mytest,true);
document.addEventListener('touchstart', mytest,true);
Шаг 03
В вашу функцию приложения
function mytest(){
// start for read (get the file and pass it on readFile method)
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
(fs)=> {
var fileName = "test.txt",
fileDir = cordova.file.applicationDirectory.replace( cordova.file.applicationDirectory, ''), //cordova.file.applicationDirectory only get error on entry file
filePath = fileDir + fileName;
fs.root.getFile(
filePath,
null,
(fileEntry) => {
readFile(fileEntry)
}, fileEntryFail);
}, filesystemFail);
// start for write (set a file creator -> get data via var -> pass var on writeFile method)
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
(fs)=> {
var fileName = "test.txt",
fileDir = cordova.file.applicationDirectory.replace( cordova.file.applicationDirectory, ''), //cordova.file.applicationDirectory only get error on entry file
filePath = fileDir + fileName;
fs.root.getFile(
filePath,
{ create: true, exclusive: false },
(fileEntry) => {
writeFile(fileEntry, filetowrite );
}, fileEntryFail);
}, filesystemFail);
// write a file whit data
function writeFile(fileEntry, dataObj) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwrite = function() {
alert("file write");
// readFile(fileEntry); // if you wont read after write it
};
fileWriter.onerror = function (e) {
alert("Failed file write: " + e.toString());
};
fileWriter.write(dataObj);
});
}
// read a file getted
function readFile(fileEntry) {
alert('Reading file....');
fileEntry.file(function (fileEntry)
{
console.log("path to file: ",fileEntry.fullPath);
console.log("file to read: ",fileEntry.file);
var reader = new FileReader();
reader.onloadend = function()
{
alert("Successful file read");
// document.body.innerHTML = ""+this.result;
console.log("Successful file read: ",this.result);
// window.dataActive = JSON.parse(this.result);
// alert('dataActive was read as: ' + dataActive)
// displayFileData(fileEntry.fullPath + ": " + this.result);
};
reader.readAsText(fileEntry);
}, readFail );
};
// fails
function filesystemFail (err) { alert("FS: DATA FAIL"); console.log(err.code);};
function fileEntryFail (err) { alert("File entry: FAIL"); };
function writeFail (err) { alert("Writing: DATA FAIL"); };
function readFail (err) { alert("Reading: DATA FAIL"); };
//data test via var
var filetowrite = `{"message": "THIS IS SIMPLE TEST MESSAGE"}`
};
Теперь несколько важных заключительных замечаний
Очевидно, бесполезно продолжать и начальное чтение, и начальную запись который проверяет один и тот же файл или данные. Либо запишите файл, а затем прочитайте его или возьмите его локально и прочитайте его напрямую. Поэтому для ваших тестов комментируйте один из двух за раз.
Также глупо держать их отдельно, потому что было бы легко оптимизировать систему, вызывая файловую систему только один раз.
Однако Я оставил их отдельно, чтобы дать ясный и функциональный пример тем, кто, как и я, застрял в логи c.
Обновление
Решение:
В ожидании сборки всего плагина, который я тестирую:
A) вам необходимо "разблокировать" доступ к файлам в конфигурации. xml, как я объяснил выше.
B) Cordova-file-plugin может только записывать, читать, удалять файлы в постоянной памяти внутри приложения. (Я выпущу модель получше, чем приведенную выше, как только смогу)
C) fetch не работает ни в коем случае. БУДЬТЕ ОСТОРОЖНЫ, он работает только в браузере, но не в приложении
D-1) Я проверяю запись и удаление файлов на www. Мне все еще нужно время.
D-2) можно прочитать запрос XML в файле www in следующим образом:
var _filename = 'MYFILENAMEINWWW.txt',
_mimetype = 'text/plain'; // or application/json
function readfromwww(_mimetype,_filename,callback)
{
var request = new XMLHttpRequest();
request.overrideMimeType(_mimetype );
request.open("GET", _filename );
request.onreadystatechange = () =>
{
if(request.status > 300)
{
if(rs==404) console.log('file not found in www: ',request.status);
else console.log('error on request: ',request.status);
}
else if(request.responseText!=undefined && request.responseText!='')
{
//from json string to js obj content
if(_mimetype == "application/json")
callback(JSON.parse(request.responseText));
//return string into your file
else
callback(request.responseText);
}
}
request.send();
}
}
// now you can read a file in www calling the method:
readfromwww('text/plain', 'test.txt',
filecontent => {
console.log('OLE! INTO THE FILE: ',filecontent);
//not filecontent is the content of your file but... remember... the contents is loaded via ajax, isn't easy to storize it out this function.
});