Electron加载本地文件
我们在使用electron时,有时会涉及一些文件的处理,比如文件的下载,或者本地文件的加载(本地音乐,本地图片等),本章主要介绍electron本地文件的加载。
其实这个功能还是比较常见的,比如我们下载了某某皮肤主题本地,想在本地加载,或者是做一个音乐播放器,加载本地音乐进行播放。
目标:使用input file获取图片或者音乐文件的本地地址(当然你可以直接用已有文件的本地地址),进行展示和播放。
web本地文件加载
浏览器为了安全考虑,在web页面进行文件加载时,是禁用了file://
协议进行文件展示的,一般来说要想获取本地文件展示,得让用户进行input file选择,获取File对象,对这个File对象进行操作展示:
<a-upload
:customRequest="customRequest"
name="file"
:showUploadList="false"
:multiple="true"
>
<a-button>
<upload-outlined></upload-outlined>
添加图片
</a-button>
</a-upload>
<a-image
:width="200"
:height="200"
:src="state.image"
/>
function customRequest(fileData) {
const file = fileData.file
state.image = window.URL.createObjectURL(file)
// 或者:
if (file) {
var reader = new FileReader()
reader.onload = function (evt) {
state.image = evt.target.result
}
reader.onerror = function (evt) {
console.error(evt)
}
reader.readAsDataURL(file)
}
}
比如在进行图片的本地显示时,使用createObjectURL直接创建url对象进行展示或者使用readAsDataURL将其转化为base64进行展示。
当然在electron中一切都变得简单起来,我们可以使用本地路径加载文件,当然得进行一些小处理。
electron本地文件加载
比如说我们已知一个本地图片的路径,假设这个路径为下载文件夹中C:\Users\Administrator\Downloads\1.png
,我们将这个地址赋值给img的src:
<a-upload
:customRequest="customRequest"
name="file"
:showUploadList="false"
:multiple="true"
>
<a-button>
<upload-outlined></upload-outlined>
添加图片
</a-button>
</a-upload>
<a-image
:width="200"
:height="200"
:src="state.image"
/>
function customRequest(fileData) {
const path = fileData.file.path
state.image = path
}
这里的path就是本地文件的地址,当你赋值之后发现图片并不能加载,会报一个net::ERR_UNKNOWN_URL_SCHEME
的错误,这是由于直接添加本地路径的话,加载文件实际上是通过file://
协议进行加载的,默认情况下chromium并不能通过file://
协议来读取文件,参考链接, 故并不能直接显示出来,本来可以设置chromium启动参数
(–-allow-file-access-from-files)来解决这个问题,但是比较遗憾electron并不吃这个一套:
// 无效
app.commandLine.appendSwitch('allow-file-access-from-files', true)
我们需要对这个本地路径进行处理,让其不通过file://
协议加载,那么如何实现呢?
我们可以通过protocol
模块来注册自定义协议并拦截现有协议请求,比如我们实现一个atom://
协议加载音乐文件进行播放:
主进程:
app.whenReady().then(() => {
// 这个需要在app.ready触发之后使用
protocol.registerFileProtocol('atom', (request, callback) => {
const url = request.url.substr(7)
callback(decodeURI(path.normalize(url)))
})
})
渲染进程:
<a-upload
:customRequest="customRequest"
name="file"
:showUploadList="false"
:multiple="true"
>
<a-button>
<upload-outlined></upload-outlined>
添加本地音乐
</a-button>
</a-upload>
<audio :src="state.audio" controls>
</audio>
function customRequest(fileData) {
const path = 'atom:///' + fileData.file.path
state.audio = path
}
原来呢我们是直接赋值类似于C:\Users\Administrator\Downloads\1.png
,我们在这个路径上加上atom:///
变为atom:///C:\Users\Administrator\Downloads\1.png
(mac同理,atom是一样的),当匹配到atom时,就会拦截这个协议请求,返回一个本地路径。这里需要注意的一点是如果我们的路径有中文名,那么获取的url
是encodeURI编码后的,我们在callback回调时需要用decodeURI
进行解码。
注册了自定义协议之后,我们只需在加载本地路径时,在前面加上atom:///
(其他名也可,自定义)即可。
本系列更新只有利用周末和下班时间整理,比较多的内容的话更新会比较慢,希望能对你有所帮助,请多多star或点赞收藏支持一下
本文地址:https://xuxin123.com/electron/local-file
本文github地址:链接
厉害!现在主要从事electron开发了吗?
哈哈,没有,写过一段时间electron,现在还是在写业务
赞! 非常牛的办法,因为要加载个10M的图片资源,找了半天觉得这个最好!
我使用atom,也还是不行,
Refused to load the image ‘atom:///D:\items****\cc4b8739b084622a.jpg’ because it violates the following Content Security Policy directive: “default-src ‘self’ ‘unsafe-inline’ data:”. Note that ‘img-src’ was not explicitly set, so ‘default-src’ is used as a fallback.
请查看你meta标签是否使用了Content Security Polily限制了加载策略
请问大佬,用这个办法,如果地址是这样的:app://abc/1.png?123,就无法找到文件。怎么破?
你需要在图片后面加上参数吗,不建议这么做,因为查找的是本地图片的实际地址,本地图片是没有?123这个参数的,要么你可以在渲染进程进行src赋值时进行url.split(“?”)[0]把后缀参数去除掉,要么在主进程自定义协议拦截那边也使用同样的方式去除掉后缀(callback(decodeURI(path.normalize(url.split(“?”)[0])))),前者的地址不会带上?123,后者带上也能展示