cordova-android icon indicating copy to clipboard operation
cordova-android copied to clipboard

WebViewAssetLoader: Application private path Raw File access at JavaScript using XMLHttpRequest fails.

Open NitzDKoder opened this issue 4 years ago • 2 comments

1) Image residing in Application private path. lFileUrl =data/user/0/com.company.stub/files/myfolder/IMG-20210826-204423558thumb.jpg

2)XMLHttpRequest request done from javascript level in cordova based android app.

var xhr = new XMLHttpRequest(); xhr.open("GET", lFileUrl, true); xhr.responseType = "blob"; xhr.onload = function(e) { try { }

3)WebResourceResponse shouldInterceptRequest called. 2021-08-26 20:44:34.534 32333-4065/com.company.stub D/SystemWebViewClient: shouldInterceptRequest request.getUrl(): https://localhost/data/user/0/com.company.stub/files/myfolder/IMG-20210826-204423558thumb.jpg

https://github.com/apache/cordova-android/blob/015db819aed3f35892d2b6035781ea4bd752149d/framework/src/org/apache/cordova/engine/SystemWebViewClient.java#L423

4)File not found exception seen as its searching in "www/"

https://github.com/apache/cordova-android/blob/015db819aed3f35892d2b6035781ea4bd752149d/framework/src/org/apache/cordova/engine/SystemWebViewClient.java#L112

2021-08-26 20:44:34.537 32333-4065/com.company.stub E/SystemWebViewClient: www/data/user/0/com.company.stub/files/myfolder/IMG-20210826-204423558thumb.jpg

### What is expected to happen? 1)private File access should be pass. https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader.InternalStoragePathHandler

### What does actually happen?

File not found exception seen as WebViewAssetLoader.InternalStoragePathHandler is not handled. Suggest how to handle raw file access.

## Information

https://bugs.chromium.org/p/chromium/issues/detail?id=1101250 Below change works. https://github.com/apache/cordova-android/blob/015db819aed3f35892d2b6035781ea4bd752149d/framework/src/org/apache/cordova/engine/SystemWebViewClient.java#L95

if(filecaseboolean){ is = new FileInputStream(new File(path));//Imagecase
 }else{
      is = parentEngine.webView.getContext().getAssets().open("www/" + path, AssetManager.ACCESS_STREAMING);
 }

### Version information

Cordova: Android 10.1.0 device : android 11
app targetsdk : 30 .

Note: if <preference name="AndroidInsecureFileModeEnabled" value="true" /> everything works fine.

  • [ ✓] I searched for existing GitHub issues
  • [ ✓] I updated all Cordova tooling to most recent version
  • [✓ ] I included all the necessary information above

NitzDKoder avatar Aug 26 '21 15:08 NitzDKoder

Facing similiar issue when using an absolute file url:

lFileUrl = 'file:///data/user/0/com.company.stub/files/myfolder/IMG-20210826-204423558thumb.jpg'
xhr.open("GET", lFileUrl, true);
xhr.onload = function() {
   console.log('loaded');
}
try {
    xhr.send();
} catch (e) {
    console.error(e);
}

Error message on console:

Not allowed to load local resource: file:///data/user/0/com.company.stub/files/myfolder/IMG-20210826-204423558thumb.jpg

Solution could be to provide something similar to window.WkWebView.convertFilePath('your/file/path'); from cordova-ios. see https://github.com/apache/cordova-ios/blob/715c2dbfb273fb33721e8cf3f989ce7b20892d32/cordova-js-src/plugin/ios/wkwebkit.js#L28

Prototype Implementation:


async function resolveLocalFileSystemURL(uri){
        return new Promise(function (resolve, reject) {
            window.resolveLocalFileSystemURL(uri, resolve, (cause) => {
                if (cause.code == FileError.NOT_FOUND_ERR)
                    resolve(null);
                else reject({cause, uri, message: "cannot resolve local file system url"})
            });
        });
}

async function convertFilePath(uri){
   if(uri.startsWith('file://'){
      const resolved = await this.utils.resolveLocalFileSystemURL(uri);
       uri = resolved.toInternalURL().replace("cdvfile://localhost/", "https://" + location.host + "/");
   }
   return uri;
}

lFileUrl = await convertFilePath('file:///data/user/0/com.company.stub/files/myfolder/IMG-20210826-204423558thumb.jpg');
xhr.open("GET", lFileUrl, true);
xhr.onload = function() {
   console.log('loaded');
}
try {
    xhr.send();
} catch (e) {
    console.error(e);
}

Error message in chrome debugger network panel: net::ERR_CONNECTION_REFUSED

Looks like https://github.com/apache/cordova-android/blob/015db819aed3f35892d2b6035781ea4bd752149d/framework/src/org/apache/cordova/engine/SystemWebViewClient.java is missing a https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader.InternalStoragePathHandler to make file:///data/user/0/com.company.stub/files available at https://localhost/files/..... The solution should be able to provide access to all locations mentioned here: https://github.com/apache/cordova-plugin-file#android-file-system-layout

regnete avatar Sep 22 '21 07:09 regnete

Is there any workaround for this or do we need to set AndroidInsecureFileModeEnabled to true? I can't get regular <img> or fetch working throuh WebViewAssetLoader with data in applications private data, i.e. /data/user/0/com.company.stub/files/. With AndroidInsecureFileModeEnabled it works using file:/// protocol.

bobobobo avatar Feb 08 '22 08:02 bobobobo