Electron 访问本地文件

在electron旧版本中,使用

protocol.registerFileProtocol(scheme, handler)

来注册协议,这样就可以通过这个协议+本地绝对路径访问到本地资源。

不知道在哪个版本开始,废弃了这个方法,改用了如下设置

首先,先使用如下的方法,在app的ready事件触发前,注册协议。

protocol.registerSchemesAsPrivileged(customSchemes)
    · customSchemes 是个数组,数组的成员是对象,对象包含下面的属性
        · scheme `字符串` - 自定义的计划,可以被按选项注册。
        · privileges `Object` (可选)
            . standard `boolean` (可选) -默认为false
            . secure `boolean` (可选) - 默认为false
            . bypassCSP `boolean` (可选) - 默认为false
            . allowServiceWorkers `boolean` (可选) - 默认为false
            . supportFetchAPI `boolean` (可选) - 默认为false
            . corsEnabled `boolean` (可选) - 默认为false
            . stream `boolean` (可选) - 默认为 false.

比如说我注册一local-file的协议头

protocol.registerSchemesAsPrivileged([
{
    scheme: 'local-file',
    privileges: {
      standard: true,
      secure: true,
      supportFetchAPI: true
    }
  }
])

老实说privileges属性设置的是啥内容,我也不知道,官方文档没讲。

其次,app.whenReady().then(() => {})中,使用如下方法,设置该协议的响应

protocol.handle(scheme, handler)
  · scheme `string` - 要处理的方案,例httpsomy-app。:这是URL 中的前面的位。
  · handler `函数<GlobalResponse | Promise<GlobalResponse>>`
      . request GlobalRequest

完整栗子:

假设说你在html里请求了一个本地文件,url如下:

local-file://d:/file/cat.jpg

必须local-file://协议开头,才能被监听到。

const { app, net, protocol } = require('electron')
const { join } = require('node:path')
protocol.registerSchemesAsPrivileged([
  {
    scheme: 'local-file',
    privileges: {
      standard: true,
      secure: true,
      supportFetchAPI: true
    }
  }
])

app.whenReady().then(() => {
  ...其他代码
  protocol.handle('local-file', (req) => {
    const { host, pathname } = new URL(req.url)
    // 这里的req.url就是你请求的url去掉协议头的内容,比如说d/file/cat.jpg
    // 为啥盘符d后面:没了,我猜可能privileges.secure = true的关系。
    // host 对应的就是第一/前面的内容, pathname对应的就是req.url去掉那个host剩下的内容。
    // 需要返回一个response对象,直接拼接路径,然后用net.fetch()返回一个response对象
    const url = join(host + ':\\', pathname)
    return net.fetch(url)
  })
})

LICENSED UNDER CC BY-NC-SA 4.0