问题
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:
- I added the 'local-filesystem' suffix into url http://localhost:potr/local-filesystem/
- Then I added the whole path that I had after file:// e.g. http://localhost/:port/local-fileystem//Users/...
- 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