apache / cordova-plugin-file

Apache Cordova File Plugin
https://cordova.apache.org/
Apache License 2.0
741 stars 756 forks source link

File access in Browser? #412

Open GitToTheHub opened 3 years ago

GitToTheHub commented 3 years ago

Hi,

I want to run my App in a browser (Chrome), but have problems with accessing the files in the same way as on android or ios. For example, i want to store data in cordova.file.dataDirectory. On Chrome this is filesystem:file:///persistent/ but when using resolveLocalFileSystemURL, i get the error: SecurityError: 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. In the docu I read to execute Chrome with the flag --allow-file-access-from-files, but this doesn't help me.

Any Ideas?

breautek commented 3 years ago

I'm not very familiar with the browser platform but I do believe it's intended to be ran from a webserver, not from the local file system. The browser has a lot of security features in place, and a lot of features are blocked when loading content from the local file system.

You should consider installing a local webserver to test your browser app.

GitToTheHub commented 3 years ago

Thank you, but I should have written, that I'm using already a local webserver with cordova run browser. If I ouput here cordova.file.dataDirectory I get the path filesystem:file:///persistent/, but cannot resolve it.

breautek commented 3 years ago

https://github.com/apache/cordova-plugin-file/blob/ce4bfa1b9c0cfdb3e8e479a62ea41a41c7c7b53e/src/browser/FileProxy.js#L76

I see... the path appears to be hard-coded but I'm not sure why. I would assume the path should look like filesystem:<origin>/...

GitToTheHub commented 3 years ago

Wow thank you, i was searching for the place, where the urls are created. Because when i debug the cordova.file-Property, i get only 3 properties, which are filled, the rest ist empty:

applicationDirectory: http://localhost:8000/ (string),
..
dataDirectory: filesystem:file:///persistent/ (string),
cacheDirectory: filesystem:file:///temporary/ (string),
..

It wondered who adds the "filesystem"-prefix and searched in the file you referenced and found it directly at the beginning of that file: https://github.com/apache/cordova-plugin-file/blob/ce4bfa1b9c0cfdb3e8e479a62ea41a41c7c7b53e/src/browser/FileProxy.js#L37

In the comment it says

// For chrome we don't need to implement proxy methods
// All functionality can be accessed natively.

It would be so nice if it would work like this :/

brodybits commented 3 years ago

I just added the help wanted label.

GitToTheHub commented 3 years ago

Thank you :)

Kepro commented 3 years ago

This is the code that I'm using... have the same issue

static async getPersistentFS(): Promise<FileSystem> {
        if (cordova.platformId === 'browser' || cordova.platformId === 'electron') {
            return new Promise((resolve, reject) => {
                window.requestFileSystem(window.PERSISTENT, 0, (fileSystem) => {
                    FilesystemTool.fileSystem = fileSystem;
                    Logger.info('Filesystem opened!', fileSystem);
                    resolve(fileSystem);
                }, (err) => {
                    reject(err);
                    console.error('Failed open file system', err.toString());
                });
            });
        }

        return new Promise((resolve, reject) => {
            window.resolveLocalFileSystemURL(cordova.file.dataDirectory, (dirEntry) => {
                FilesystemTool.fileSystem = dirEntry.filesystem;
                resolve(dirEntry.filesystem);
            }, (err) => {
                reject(err);
                console.error('Failed open file system', err.toString());
            });
        });
samir-mahendra commented 7 months ago

I know this is an old thread, but if you are OK using the sandboxed file system (which is OK for my use case) this works for me in Chrome:

window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, (fileSystem) => {
   fileSystem.root.getDirectory("MyFiles", { create: true }, (dirEntry) => {
       dirEntry.getFile("test.txt", { create: true, exclusive: false }, (fileEntry) => {
            // Use the fileEntry to write/read from the file.
       }, (err) => { console.error("getFile", err); });
   }, (err) => { console.error("getDirectory", err); });
}, (err) => { console.error("requestFileSystem", err); });