0

I am trying to save a file locally using Apache cordova file plugin and I am getting a Security Error

My code is below

  window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function(dir) {
    console.log("got main dir", dir.name);
    dir.getFile("catalog.json", {create:true}, function(file) {
            console.log("got the file", file);
            logOb = file;
        });
  }, function(error) {
    console.log(error.message);
    console.log(error.name);
  });

Error on the console:

It was determined that certain files are unsafe for access within a Web application, or that too many calls are being made on file resources.
SecurityError

Do I need to add in allow-intent tags to enable working with files?

I think I am obviously missing something but I have tried searching on Internet without concrete results.

lifeisfoo
  • 15,478
  • 6
  • 74
  • 115
anirus
  • 1,597
  • 2
  • 18
  • 24

2 Answers2

2

Cordova mobile webviews have, by default, local file access enabled (but always ruled by the application configuration). Regular browsers have many security features enabled: one of this is the block of local file access from other files (e.g. js code).

A common source of error is the missing --allow-file-access-from-files launch parameter for Chrome. See How to launch html using Chrome at "--allow-file-access-from-files" mode? for more information about this.

Be sure to check the Cordova file plugin browser quirks also.

Another problem with your code is the use of cordova.file.dataDirectory shortcut that, according to the documentation, isn't not supported in the browser:

cordova.file.dataDirectory - Persistent and private data storage within the application's sandbox using internal memory (iOS, Android, BlackBerry 10, windows)

If you look at the cordova.file.*Directory list, you can see that the browser platform doesn't support any cordova shortcut.

Depending on the browser you're using, a path like cdvfile://localhost/persistent/file or file:///persistent/path/to/entry should be used in the browser. You can find more information about this in the browser quirks section of the documentation.

Community
  • 1
  • 1
lifeisfoo
  • 15,478
  • 6
  • 74
  • 115
  • can you elaborate on "If you look at the `cordova.file.*Directory` list". What list are you referring to? – Chase Jun 26 '17 at 04:03
  • @Chase Cordova [URLs to important file-system directories list](https://github.com/apache/cordova-plugin-file#where-to-store-files). At the end of each list element there is a list with platforms where it's available: the browser platform doesn't appears in any list. – lifeisfoo Jun 26 '17 at 07:20
  • 1
    Wow.... I feel so stupid. In my head I wasn't separating the "Windows" OS from the browser (I'm on Windows / Chrome). I realize now they're referring to actual Windows native apps. So, right you are. Browser isn't listed anywhere. But, I've tried `filesystem:file:///persistent/`, `filesystem:http://localhost:8080/persistent/`, `"filesystem:" + cordova.file.applicationDirectory + "persistent/"` (which returns the former)... but I can't shake this security error. Also running chrome with `--allow-file-access-from-files` – Chase Jun 26 '17 at 21:27
1

I got the same error while trying to save a file localy when using

 cordova build browser

with Chrome and Edge, but not with Firefox.

Thanks to the former comments I did understand, that cordova.file.dataDirectory is not supported by platform browser. After some digging I found out that in Chrome you need to use the webkit functions to access local files.

 window.webkitRequestFileSystem(window.PERSISTENT|window.TEMPORARY , [filesize], [ReadWriteFunction]);

However for all other platforms (including Firefox) we can use cordova.file.dataDirectory. In order to have a code that is applicable for all cases (android, ios, browser (with Chrome and Firefox)) we need to use window.resolveLocalFileSystemURL or when neccessary window.webkitRequestFileSystem. With this information the code of the question could be changed to.

 // Function when Folder is loaded
 successFunction = function(dir){
      console.log("got main dir", dir.name);
      dir.getFile("catalog.json", {create:true}, function(file) {
           console.log("got the file", file);
           logOb = file;
      });
 };
 
 // Function for error
 errorFunction = function(error){
      console.log(error.message);
      console.log(error.name);
 }

 if(cordova.platformId === 'browser'){
      if(typeof window.webkitRequestFileSystem !== 'undefined'){
           window.webkitRequestFileSystem(
                window.PERSISTENT , // Where to look for
                1024*1024, // request max available size ( here 1 MB), 
                function(dir){ successFunction.apply(this, [dir]); };
                function(error){ errorFunction.apply(this, [error]); };
           });
      }
 }
 
 window.resolveLocalFileSystemURL(
      cordova.file.dataDirectory, 
      function(dir){ successFunction.apply(this, [dir]); };
      function(error){ errorFunction.apply(this, [error]); };
 });

I did not check if the code of the question is running like this.

Holger
  • 53
  • 1
  • 9