我几天来一直在努力解决这个问题。我有一个使用ngCordova#0.1.26-alpha
的Ionic 1.3.0应用程序我使用$ cordovaFile.writeFile()将图像存储在cordova.file.applicationStorageDirectory中。我尝试过每个存储位置都有相同的结果。文件很好,我可以在文件管理器应用程序中查看它。我想将该文件用作<img>
的ng-src。在Android上,这可能类似于:cdvfile://localhost/sdcard/Android/data/com.example.mobile/img-49444.jpg
因此,在我的页面中,我将网址绑定到<img>
并在其中添加完整性检查<pre>
,以查看record.image_url是否具有有效的网址:
<img ng-src="{{record.image_url}}">
<pre>{{record.image_url}}</pre>
虽然网址看起来不错,但图片根本无法渲染,似乎没有多少努力会说服它。我从$ cordovaFile.writeFile的响应对象中使用了entry.toURL(),entry.toInternalURL()等尝试了file:///,cdvfile://和http:// URL。 )。所有方法都会因图像图标损坏或空<img>
元素渲染而失败。
我已尝试将此CSP标记添加到index.html(以及其他几十次尝试)
<meta http-equiv="Content-Security-Policy" content="img-src 'self' data: blob: filesystem: cdvfile://*;">
我已经尝试过使用$ compileProvider,比如:
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|cdvfile):|data:image\//);
在config.xml Cordova白名单中抛出我所能做的一切
<plugin name="cordova-plugin-whitelist" spec="~1.2.1">
<access origin="*"/>
<access origin="cdvfile://*"/>
<access origin="file://*"/>
<access origin="file:///*"/>
<allow-intent href="cdvfile://*"/>
<allow-intent href="file://*"/>
<allow-intent href="file:///*"/>
<allow-navigation href="cdvfile://*"/>
<allow-navigation href="file://*"/>
<allow-navigation href="file:///*"/>
</plugin>
没有任何作用。我不认为这是一个白名单插件问题 - 我的假设是,当图像因白名单而被拒绝时,图像显示为断开的链接,而<img>
元素则为空当白名单没有拒绝它时,不占用任何空间。此行为在Android 4.4.4和6.0.1上保持一致。
非常感谢任何帮助。
答案 0 :(得分:2)
为了不误导遇到此答案的其他人,我设法让cdvfile://
网址即使在实时加载模式下也可以在新应用中出现问题。简单地:
config.xml中
<access origin="*"/>
<access origin="tel:*" launch-external="yes"/>
<access origin="geo:*" launch-external="yes"/>
<access origin="mailto:*" launch-external="yes"/>
<access origin="sms:*" launch-external="yes"/>
<access origin="market:*" launch-external="yes"/>
<access origin="cdvfile:*"/>
<plugin name="cordova-plugin-whitelist" spec="~1.2.2"/>
请注意,<access>
规则不应嵌套在<plugin>
下。文档没有明确地说出来。
app.js
.config(function ($stateProvider, $urlRouterProvider, $compileProvider) {
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|file|blob|cdvfile|content|tel|geo|mailto|sms|market):|data:image\//);
我没有在index.html
中声明的Content-Security-Policy元标记一切都很好。
答案 1 :(得分:1)
因此,如果我将构建的.apk部署到设备而不是使用Ionic livereload服务器(离子运行android -cls),我可以使用文件:/// *路径用于ng-src。显而易见的是,硬件级功能不会像基于浏览器的ionic serve
那样起作用,但是基于livereload服务器在实际硬件上进行测试就不那么明显了。我错误地认为livereload服务器只是一种文件监控方法,它会在资产更改时将资产流式传输到设备上,并可能通知应用程序重新加载。相反,它们似乎只是直接在您的主机上托管Web服务器。 $ cordovaFile即使在livereload中也能正确读取/写入设备上的文件,但应用程序中的Web视图不能以该模式对设备上的文件进行本机访问。我可以使用$ cordovaFile.readAsText()读取文件内容,即使在livereload上也能正常工作,但是当涉及到应用程序中的Web视图到达文件时,它只是没有任何访问本机的权限设备网址。
如果有其他人遇到此问题,请按照以下方式编写文件并捕获网址以便在视图中使用。
$ionicPlatform.ready(function () {
var targetDir = cordova.file.externalApplicationStorageDirectory + "files/";
$cordovaFile.writeFile(targetDir, name, imageData, true)
.then(function (info) {
console.log("File created", info.target.localURL, JSON.stringify(info));
$cordovaFile.checkFile(targetDir, name).then(function (entry) {
console.log("Got file entry", entry.toURL());
q.resolve(entry.toURL());
});
}, function (e) {
q.reject(e);
});
});
return q.promise;
}
在Android上,这将返回一个URL,如:
file:///storage/emulated/0/Android/data/com.example/files/<name>
我发现在config.xml中cordova-plugin-whitelist可以为空 - 我们不需要任何针对file:///的白名单指令。此外,不需要$ compileProvider.imgSrcSanitizationWhitelist()更改 - 默认白名单应该工作。
无论白名单设置,Content-Security-Policy指令或app.config调整,我都没有让cdvfile:// URL工作。