WebViewAssetLoader: Application private path Raw File access at JavaScript using XMLHttpRequest fails.
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
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
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.