使用cordova-plugin-camera获取本地图片,<img>标签加载报连接拒绝求助
解决方案:Cordova Camera 本地图片展示 ERR_CONNECTION_REFUSED 问题
问题原因
你遇到的net::ERR_CONNECTION_REFUSED错误,是因为Cordova Android 10+版本中,entry.toURL()返回的https://localhost/__cdvfile_sdcard__/...格式URL依赖Cordova本地服务器的特殊路由处理,但当前配置下该路由未正确生效。同时大尺寸图片用Data URL会导致内存占用过高,因此需要采用直接访问本地文件的方案。
可行解决方案
1. 改用nativeURL替代toURL()
resolveLocalFileSystemURL返回的FileEntry对象的nativeURL属性是标准的file://协议路径,WebView可直接加载,无需经过本地服务器转发:
修改你的成功回调函数:
const onsuccess = function (entry) { // 使用nativeURL而非toURL() image.src = entry.nativeURL; // 此时路径为 "file:///storage/emulated/0/DCIM/Camera/20220208_140605.jpg" }
2. 配置Cordova允许file://访问
在项目根目录的config.xml中添加以下偏好设置,确保WebView允许加载file://协议的资源:
<preference name="AllowFileAccess" value="true" /> <preference name="AllowUniversalAccessFromFileURLs" value="true" />
3. 确保文件权限已正确请求
使用cordova-plugin-android-permissions在运行时请求存储权限,添加以下代码在调用getPicture之前:
async function requestPermissions() { const permissions = cordova.plugins.permissions; const status = await permissions.checkPermission(permissions.READ_EXTERNAL_STORAGE); if (!status.hasPermission) { const result = await permissions.requestPermission(permissions.READ_EXTERNAL_STORAGE); if (!result.hasPermission) { throw new Error("存储权限被拒绝"); } } } // 在获取图片前调用权限请求 await requestPermissions(); let url = await getPicture();
4. 适配Android 10+分区存储
Cordova Android 10+默认适配分区存储,cordova-plugin-camera@6.0.0已支持该特性,但需确保config.xml中未禁用分区存储:
<!-- 确保没有以下禁用配置 --> <!-- <preference name="AndroidInsecureFileModeEnabled" value="true" /> -->
验证修改后的完整代码
async function requestPermissions() { const permissions = cordova.plugins.permissions; const status = await permissions.checkPermission(permissions.READ_EXTERNAL_STORAGE); if (!status.hasPermission) { const result = await permissions.requestPermission(permissions.READ_EXTERNAL_STORAGE); if (!result.hasPermission) { throw new Error("存储权限被拒绝"); } } } const getPicture = () => new Promise((resolve, reject) => { navigator.camera.getPicture(data => resolve(data), msg => reject(msg), { destinationType: Camera.DestinationType.FILE_URI, sourceType: Camera.PictureSourceType.PHOTOLIBRARY, mediaType: Camera.MediaType.ALLMEDIA, allowEdit: true, }); }); // 主逻辑 async function loadImage() { try { await requestPermissions(); let url = await getPicture(); const onsuccess = function (entry) { image.src = entry.nativeURL; } const onerror = function (err) { console.error(`error : ${err.code}`); } if (!url.startsWith('file://')) { url = `file://${url}`; } window.resolveLocalFileSystemURL(url, onsuccess, onerror); } catch (err) { console.error(err); } }
内容的提问来源于stack exchange,提问作者pius lee
相关产品推荐
相关产品推荐

