Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unsupported URL error for a cdvfile://

Problem:

In my app, I want to access an image through cordova wkwebview. The HTML element looks as follows.

<img src="cdvfile://localhost/library-nosync/MyFolder/file.jpg">

While loading this, I get error "Failed to load resource: unsupported URL". I am working with iOS 10.2.

Things verified/tried:

If list of files present in "cordova.file.dataDirectory" under folder "MyFolder" is checked, I do see the "file.jpg" present there. It has the native URL as file:///var/mobile/Containers/Data/Application/app_id/Library/NoCloud/MyFolder/file.jpg.

I have added "img-src 'self' cdvfile: " to the Content-Security-Policy.

I have added following in the config.xml

<access origin="cdvfile://*" /> 
<allow-navigation href="cdvfile://*" /> 
<allow-intent href="cdvfile://*" />
<preference name="iosPersistentFileLocation" value="Compatibility" />
<preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" />

There are no special (non-ASCII) characters in the URL as mentioned in threads relating to this error. What else could be the reason of "Unsupported URL"?.

Is the way I am accessing cdvfile:// path incorrect?

Update

I came across a link (forgot to capture that) saying the webview needs relative path and hence cdvfile:// would not work. I tried to change the image source to a relative path by changing it to "../../../../../../../../..//var/mobile/Containers/Data/Application/app-id/Library/NoCloud/MyFolder/file.jpg" and I could now see a new error - "Failed to load resource: The operation couldn’t be completed. Operation not permitted"

I could get the image working by "reading" the contents of the file and passing that base64 data as image source. But that is not how it should be, should it?

like image 362
Amruta Avatar asked Mar 13 '17 09:03

Amruta


2 Answers

If you use the newest ios platform ([email protected]) you can use the scheme and host name options:

<preference name="scheme" value="app" />
<preference name="hostname" value="localhost" />

Then you should get and use the schemeUrl (app://) instead of the cdvfile:// or file:// url.

var cdvfileUrl = "cdvfile://localhost/library-nosync/MyFolder/file.jpg";

// Convert to native url
window.resolveLocalFileSystemURL(cdvfileUrl, function(entry) {
    var nativeUrl = entry.toNativeURL(); // will be "file://...."

    // Use nativeUrl to get scheme friendly url
    var schemeUrl = window.WkWebView.convertFilePath(nativeUrl);  // Will be "app://..."
});

You can use this schemeUrl in your your <img> src tag.

like image 154
Lindsay-Needs-Sleep Avatar answered Sep 18 '22 07:09

Lindsay-Needs-Sleep


For Future reference, with the latest WKWebView, the direct setting of the src attribute fails.

Only way I've found to load the image is something like this:

    function loadImageFromFile(filename, imgElement) {
        // filename is cdvfile:....... (string)
        // imgElement is target IMG element name (string)
        window.resolveLocalFileSystemURL(filename, function success(fileEntry) {
            fileEntry.file(function (file) {
                var reader = new FileReader();
                reader.onloadend = function() {
                    if (reader.result) {
                        var elem = document.getElementById(imgElement);
                        var blob = new Blob([new Uint8Array(reader.result)], { type: "image/png" });
                        elem.src = window.URL.createObjectURL(blob);
                        window.URL.revokeObjectURL(blob);
                    }
                };
                reader.readAsArrayBuffer(file);
            });
        }, function () {
            console.log("File not found: ");
        });
    }
like image 44
ferdil Avatar answered Sep 18 '22 07:09

ferdil