[英]How can I read / write a local json or text in Cordova?
I'm trying to read a JSON file inside the www with Cordova.我正在尝试使用 Cordova 读取 www 中的 JSON 文件。
I'm trying with a lot of systems, tests and solutions which, however, are failing one after the other.我正在尝试许多系统、测试和解决方案,但是,它们一个接一个地失败了。
Result: locally work.结果:本地工作。 On app: "fetch fail" if use
cordova.file.dataDirectory
.在应用程序上:如果使用
cordova.file.dataDirectory
则“获取失败”。 The result is: "NetworkError when attempting to fetch resource".结果是:“尝试获取资源时出现网络错误”。
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);
});
};
Result: security on file.结果:文件安全。 You can't get file, so you can't read it.
您无法获取文件,因此无法读取它。
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();
Result: file not found or encoding error.结果:找不到文件或编码错误。
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) );
I'm continuing to do many tests but I don't understand what is going wrong.我继续做很多测试,但我不明白出了什么问题。 I don't understand why it is so difficult to read a local file in the www folder of Cordova.
我不明白为什么读取Cordova 的www 文件夹中的本地文件如此困难。
How can I do this?我怎样才能做到这一点?
Over 32 tests after, the solution was wrong.经过32次测试,解决方案是错误的。
Unfortunately I just realized that he doesn't write the file from the www folder.不幸的是,我刚刚意识到他没有从 www 文件夹中写入文件。 What you can do is "create a file from the variable, historicize it in the permanent and then reread it. It still doesn't read as I wanted then.
您可以做的是“从变量创建一个文件,将其历史化,然后重新读取它。它仍然没有按照我想要的方式读取。
What happened during the test is simply the result of previous tests where I had "copied the file into the variable by hand", therefore I had unknowingly saved it and was subsequently recovered as if it were reading the local one (which, of course, was identical)测试期间发生的事情只是之前测试的结果,我“手动将文件复制到变量中”,因此我在不知不觉中保存了它,随后被恢复,好像它正在读取本地文件(当然,是相同的)
Unfortunately I still can't find a solution to read the file.不幸的是,我仍然找不到读取文件的解决方案。 If you are aware of it, write!
如果你知道它,写!
For this example we have 2 type of data.对于这个例子,我们有 2 种类型的数据。
1) is a simple var within a json message; 1) 是 json 消息中的一个简单变量;
2) It's a local file in the directory www (then create a file by hand that you can recover ... a text with false json data similar to the one in 1) 2)它是www目录下的本地文件(然后手工创建一个可以恢复的文件......一个类似于1合1的带有假json数据的文本)
add cordova-file-plugin in your project在您的项目中添加cordova-file-plugin
https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/index.html https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/index.html
In config.xml在 config.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>
Potentially you may also need to enter:您可能还需要输入:
<access origin="*" /> <access origin="cdvfile://*"/> <access origin="file:///*"/>
Now, after app is ready, example:现在,在应用程序准备好后,例如:
if('cordova' in window)
{
document.addEventListener('deviceready', mytest);
// console.log('device');
}
else
{
document.addEventListener('DOMContentLoaded', mytest);
// console.log('web device');
}
in alternative joint it on event:或者在事件中联合它:
document.addEventListener('click', mytest,true);
document.addEventListener('touchstart', mytest,true);
Into your function of app进入你的应用功能
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"}`
};
It is obviously useless to keep both start read and start write which test on the same file or data.在同一个文件或数据上同时保持 start read 和 start write 显然是没用的。 Either write the file and then read it or take it locally and read it directly.
要么写入文件然后读取它,要么在本地获取它并直接读取它。 So for your tests comment one of the two at a time.
因此,对于您的测试,一次评论两个中的一个。
It's also stupid to keep them separate because it would be easy to optimize the system by calling the file system only once.将它们分开也很愚蠢,因为只需调用一次文件系统就可以很容易地优化系统。
However, I left them separate to give a clear and functional example to those who, like me, are stuck on logic.但是,我将它们分开,以便为那些像我一样坚持逻辑的人提供一个清晰而实用的示例。
Solution:解决方案:
While waiting for the whole plugin I am testing to be built:在等待构建我正在测试的整个插件时:
A) you have to "unlock" access to files in config.xml as I explained above. A)你必须“解锁”对 config.xml 中文件的访问,正如我上面所解释的。
B) cordova-file-plugin can only write, read, delete files in the permanent memory inside the app. B)cordova-file-plugin 只能在应用程序内部的永久内存中写入、读取、删除文件。 (I will release a better model than the one above as soon as I can)
(我会尽快发布比上面更好的模型)
C) fetch does not work in any case. C) fetch 在任何情况下都不起作用。 BE CAREFUL, it only works on the browser but not in the app
小心,它只适用于浏览器而不适用于应用程序
D-1) I am testing the writing and deleting of files in the www. D-1) 我正在测试 www 中文件的写入和删除。 I still need time.
我还需要时间。
D-2) it is possible to read through an XML request the file in the www in the following way: D-2) 可以通过以下方式通过 XML 请求读取 www 中的文件:
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.
});
You can check out MongOGX which is a front end db inspired by MongoDB where you can save JSON documents and it supports cordova您可以查看 MongOGX,这是一个受 MongoDB 启发的前端数据库,您可以在其中保存 JSON 文档并支持cordova
MongOGX is a simple JavaScript based document store/database inspired by MongoDB.
MongOGX 是一个简单的基于 JavaScript 的文档存储/数据库,受 MongoDB 启发。 It supports local storage and application data storage (via Cordova - cordova-plugin-file) storage modes.
它支持本地存储和应用程序数据存储(通过 Cordova -cordova-plugin-file)存储模式。 It also supports encryption (via code.google.com/p/crypto-js - added to this repo).
它还支持加密(通过 code.google.com/p/crypto-js - 添加到此存储库中)。
See https://github.com/globules-io/MongOGX见https://github.com/globules-io/MongOGX
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.