Why is my IOS app rejecting cdvfile:// and file:/// links?

烈酒焚心 提交于 2019-12-01 16:21:04

问题


I'm having a problem displaying images downloaded to cordova.file.dataDirectory in my angular/ionic/cordova app.

I'm using cordova-plugin-file and I'm able to download the files, and extract the URLS using .toInternalURL() and/or .toURL(). However the angular list view is rejecting them. I'm using WkWebView for Ios, and my code is working fine on Android (using .toInternalURL() ). I've whitelisted both cdvfile://* and file:///* in the config and in the meta content-security-policy...

I've added screenshots Here's the console screenshot for links generated by .toInternalURL()

Here's the screenshot for links generated by .toURL():

Here's the security policy im using:

<meta http-equiv="Content-Security-Policy" content="default-src * data: cdvfile://* content://* file:///*; style-src 'self' 'unsafe-inline' *; script-src 'self' 'unsafe-inline' 'unsafe-eval' *; media-src *">

回答1:


Ok, so it turns out that my problem was WKWEBVIEW. I had been using it and didn't realize it was the source of my issue.

So to use a stored image path in src attribute, don't use cdvfile:// or file:///. Instead create a path that looks like this:

http://localhost:12344/Library/NoCloud/ho_tylw7Ygc.jpg

Prepend "http://localhost:12344/Library/NoCloud" to entry.fullPath and you're all set to point to your app's dataDirectory.




回答2:


To make it work I had to do the following trick:

  1. I added the 'local-filesystem' suffix into url http://localhost:potr/local-filesystem/
  2. Then I added the whole path that I had after file:// e.g. http://localhost/:port/local-fileystem//Users/...
  3. But to make things work, if you look at the document.location.href, you will see cdvToken parameter. It needs to be added to the url you baked as ?cdvToken=blah-blah-blah

Only afterwards the thing started to work. Note that I use 'local-webserver' npm pacakge as a cordova-labs-local-webserver (version 1.0.0-dev.) Things can be different in other versions.




回答3:


For people using Ionic 3, this did do the trick for me:

import {normalizeURL} from 'ionic-angular';

normalizeURL(cordova.file.dataDirectory + file.fullPath)

Maybe this is more bulletproof, because it relies on cordova.file.dataDirectory rather then a hard coded string




回答4:


Another approach that doesn't involve using a local webserver is to create a URL using URL.createObjectURL from a blob. Just make sure you revoke the URL when you've finished using it to avoid memory leaks.

Note that you'll need to add "blob:" to your default-src in Content-Security-Policy:

To do this you need to read the file entry as an ArrayBuffer, create a blob, then create a URL, this URL works fine for videos and images provided you added "blob:" to Content-Security-Policy

const reader = new FileReader();
reader.onloadend = function() {
    const blob = new Blob([this.result]);
    url = URL.createObjectURL(blob));
};
reader.readAsArrayBuffer(fileentry);

When you've finished with it, say when they move to another page revoke the URL:

URL.revokeObjectURL(url)

I have a helper module that keeps track of all the URLs and when the route changes I call clearBlobURLs which revokes them all.

const urls:string[] = [];

function createBlobURL(blob:Blob) : string {
    const url = URL.createObjectURL(blob);
    urls.push(url);
    return url;
}

function clearBlobURLs() {
    urls.forEach(url => {
        URL.revokeObjectURL(url);
    })
}

export {createBlobURL,clearBlobURLs};


来源:https://stackoverflow.com/questions/32546965/why-is-my-ios-app-rejecting-cdvfile-and-file-links

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!