为什么我的IOS应用程序拒绝cdvfile://和file:///链接?

时间:2015-09-13 06:31:30

标签: ios angularjs cordova filesystems cordova-plugin-file

我在使用angular / ionic / cordova应用程序显示下载到cordova.file.dataDirectory的图像时遇到问题。

我正在使用cordova-plugin-file,我可以下载文件,并使用.toInternalURL()和/或.toURL()提取URL。但是,角度列表视图拒绝它们。我正在使用WkWebView for Ios,我的代码在Android上工作正常(使用.toInternalURL())。我已在配置和meta content-security-policy中将cdvfile:// *和file:/// *列入白名单......

我添加了截图 这是.toInternalURL()生成的链接的控制台屏幕截图

以下是.toURL()生成的链接的屏幕截图:

以下是我使用的安全策略:

<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 *">

4 个答案:

答案 0 :(得分:6)

好的,事实证明我的问题是WKWEBVIEW。我一直在使用它,并没有意识到这是我的问题的根源。

因此,要在src属性中使用存储的图像路径,请不要使用cdvfile://或file:///。而是创建一个如下所示的路径:

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

将“http://localhost:12344/Library/NoCloud”添加到entry.fullPath,您就可以指向应用的dataDirectory。

答案 1 :(得分:1)

为了使它工作,我必须做以下技巧:

  1. 我添加了本地文件系统&#39;后缀为网址http://localhost:potr/local-filesystem/
  2. 然后我添加了文件后的整个路径://例如http://localhost/:port/local-fileystem//Users/ ...
  3. 但是为了使事情有效,如果你看一下document.location.href,你会看到cdvToken参数。它需要添加到您烘焙的URL中?cdvToken = blah-blah-blah
  4. 事后才开始工作。 请注意,我使用的是本地网络服务器&#39; npm pacakge作为cordova-labs-local-webserver(版本1.0.0-dev。) 其他版本的情况可能有所不同。

答案 2 :(得分:0)

对于使用Ionic 3的人来说,这确实帮了我大忙:

import {normalizeURL} from 'ionic-angular';

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

也许这更防弹,因为它依赖cordova.file.dataDirectory而不是硬编码的字符串

答案 3 :(得分:0)

另一种不涉及使用本地Web服务器的方法是使用Blob中的URL.createObjectURL创建URL。只要确保在使用完URL后就将其吊销即可,以避免内存泄漏。

请注意,您需要在Content-Security-Policy:

中的default-src中添加“ blob:”

为此,您需要以ArrayBuffer的形式读取文件条目,创建一个blob,然后创建一个URL,如果您在Content-Security-Policy中添加了“ blob:”,该URL就可以很好地用于视频和图像

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

完成操作后,说出他们移至另一页时撤消URL:

URL.revokeObjectURL(url)

我有一个帮助程序模块,该模块可以跟踪所有URL,并且当路由更改时,我会调用clearBlobURLs来撤消所有URL。

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};