Cordova - 在 <img> 标签中显示本地图像文件
Posted
技术标签:
【中文标题】Cordova - 在 <img> 标签中显示本地图像文件【英文标题】:Cordova - Displaying local image files in a <img> tag 【发布时间】:2018-12-13 13:49:05 【问题描述】:我有一个 Cordova 应用程序(基于 Ember.js,使用 Corber 插件构建),我目前只在 ios 上运行,特别是 iOS 模拟器(iPhone 8,iOS v12),所以它使用WKWEBVIEW
。
该应用程序正在使用cordova的文件插件下载远程图像并将它们存储在用户的设备上,目前在“文档”(cordova.file.documentsDirectory
)中,它工作正常,并且我已经验证图像确实存在那里。但是,我无法通过标准 <img>
标签找出正确的 URL/URI 来在应用程序中显示这些图像。
Cordova 自己的文档说要使用 cdvfile://
协议路径 (https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/#cdvfile-protocol),但即使按照那里的说明进行操作(将 content-security 元标记添加到 index.html,将访问规则添加到 config.xml等),似乎 WKWEBVIEW 完全不支持此协议,当我尝试使用它时,控制台中出现“不支持的 URL”错误。
关于该主题的其他 SO 答案建议使用相对于 cordova 应用程序的 Web 服务器 URL 的正常 URL 路径,例如<img src="/Library/NoCloud/path-to-my/file.jpg">
之类的东西,但我尝试 404 的任何路径。
这似乎是一个简单/常见的用例,但我很难过。
【问题讨论】:
难道不能通过base64(readAsDataURL)吗? 【参考方案1】:对于像我一样苦苦挣扎的其他人 - 还有一个解决方案,它不需要对我在似乎没有解决方案可用的绝望日子后发现的代码进行重大更改
需要两个步骤:
首先使用以下更新您的 config.xml
<platform name="ios">
<preference name="scheme" value="app" />
<preference name="hostname" value="localhost" />
</platform>
然后使用未记录的方法转换您的 file:// 链接
window.WkWebView.convertFilePath(filePath)
此方法执行转换为虚拟 localhost 链接,使文件可访问并绕过 WkWebView 限制。稍微长一点的样本是这样的
let localFile = cordova.file.dataDirectory + 'logo.png';
let convertedPath = window.WkWebView.convertFilePath(localFile);
document.getElementById("myImg").src = convertedPath;
【讨论】:
这里的窗口是什么?我们如何获取 window.WKWebView.convertFilePath() 方法?【参考方案2】:我没有使用 Cordova,但您链接的文档是这样说的:
要将 cdvfile 用作标签的 src,您可以通过解析后的 fileEntry 的 toURL() 方法将其转换为本机路径,您可以通过 resolveLocalFileSystemURL 获得 - 请参见下面的示例。
并以此为例:
resolveLocalFileSystemURL('cdvfile://localhost/temporary/path/to/file.mp4', function(entry)
var nativePath = entry.toURL();
console.log('Native URI: ' + nativePath);
document.getElementById('video').src = nativePath;
鉴于这一切,我想说您可以尝试创建一个组件,cdv-img
。我认为这样的事情应该可行:
import Component from '@ember/component';
export default Component.extend(
tagName: 'img',
cdvPath: undefined,
didReceiveAttrs()
this._super(...arguments);
if (this.cdvPath)
resolveLocalFileSystemURL(this.cdvPath, (entry) =>
this.$().attr('src', entry.toURL());
);
,
);
像这样使用它:
cdv-img cdvPath='cdvfile://localhost/temporary/path/to/file.jpg'
更新
如果不支持文件协议,可以尝试将图片转成数据url
import Component from '@ember/component';
export default Component.extend(
tagName: 'img',
cdvPath: undefined,
didReceiveAttrs()
this._super(...arguments);
if (this.cdvPath)
const el = this.$();
resolveLocalFileSystemURL(this.cdvPath, (entry) =>
entry.file(function (file)
const reader = new FileReader();
reader.onloadend = function()
el.attr('src', this.result);
;
reader.readAsDataURL(file);
);
);
,
);
【讨论】:
是的,我最初有类似的东西,试图只使用toUrl()
返回的本机路径,但问题是返回file:///path/to/file.jpg
形式的URI,而这并没有在 iOS 模拟器中工作,我收到“不允许本地文件 url”的内容安全错误。
@BillDami 您可以尝试转换为数据网址(请参阅更新的答案)
谢谢,是的,我看到其他答案也表明了这一点,不幸的是,我无法承担转换为数据 url 会产生的额外处理开销,因为应用程序正在以非常快速的方式。
@BillDami 你测量过开销吗?这可能是可以接受的。但如果没有,那我就没有更多的想法了。【参考方案3】:
确保您不要忘记添加这两行并尝试您正在尝试的任何解决方案,添加它们后我得到了我的图像:
在您的 config.xml 文件中。添加:
<preference name="allowFileAccessFromFileURLs" value="true" />
<preference name="allowUniversalAccessFromFileURLs" value="true" />
【讨论】:
以上是关于Cordova - 在 <img> 标签中显示本地图像文件的主要内容,如果未能解决你的问题,请参考以下文章
外部图像未在 Android 应用程序中显示 - Meteor - Cordova