ngCordova cdvfile URL和ng-src不呈现图像

时间:2016-04-27 22:28:58

标签: android angularjs cordova ionic-framework

我几天来一直在努力解决这个问题。我有一个使用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上保持一致。

非常感谢任何帮助。

2 个答案:

答案 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工作。