【Electron Playground 系列】自定义协议篇

作者: OBKoro1

1. 协议: 从网页端唤起Electron应用

elelctron提供了一个方式来自动唤起electron应用(如下图),这一次就让我们来学学如何通过连接来唤起electron应用,并且我们可以使用这个功能来做点什么

1.1 协议唤起示例:

setProtocol.gif

1.2 什么是协议

electron注册的协议, electron会将协议注册到系统的协议列表中,它是系统层级的API,只能在当前系统下使用, 其他未注册协议的电脑不能识别。

Electron的app模块提供了一些处理协议的方法, 这些方法允许您设置协议和取消协议, 来让你的应用成为默认的应用程序。

1.3 协议的作用

注册一个协议到系统协议中, 当通过其他应用/浏览器网页端打开新协议的链接时,浏览器会检测该协议有没有在系统协议中, 如果该协议注册过,然后唤起协议的默认处理程序(我们的应用)

1.4 注册协议: app.setAsDefaultProtocolClient

协议需要在ready事件后注册,具体代码如下.

// 注册自定义协议
const { app } = require('electron')
const path = require('path')

// 注册自定义协议
function setDefaultProtocol() {
  const agreement = 'electron-playground-code' // 自定义协议名
  let isSet = false // 是否注册成功

  app.removeAsDefaultProtocolClient(agreement) // 每次运行都删除自定义协议 然后再重新注册
  // 开发模式下在window运行需要做兼容
  if (process.env.NODE_ENV === 'development' && process.platform === 'win32') {
    // 设置electron.exe 和 app的路径
    isSet = app.setAsDefaultProtocolClient(agreement, process.execPath, [
      path.resolve(process.argv[1]),
    ])
  } else {
    isSet = app.setAsDefaultProtocolClient(agreement)
  }
  console.log('是否注册成功', isSet)
}

setDefaultProtocol()

1.5 使用协议

使用方式: 在浏览器地址栏输入注册好的协议,即可唤起应用。

协议唤起的链接格式: 自协议名称://参数

比如上文注册: electron-playground-code协议,触发时会默认带上://

在使用的时候, 需要在浏览器地址栏输入:

electron-playground-code://1234 // 1234是参数 可根据业务自行修改

1.6 注册协议并通过浏览器唤起后台应用的gif示例:

setProtocol.gif

1.7 监听应用程序被唤起

应用程序唤起,mac系统会触发open-url事件,window系统会触发second-instance事件。

// 注册自定义协议
const { app, dialog } = require('electron')
const agreement = 'electron-playground-code' // 自定义协议名
// 验证是否为自定义协议的链接
const AGREEMENT_REGEXP = new RegExp(`^${agreement}://`)

// 监听自定义协议唤起
function watchProtocol() {
  // mac唤醒应用 会激活open-url事件 在open-url中判断是否为自定义协议打开事件
  app.on('open-url', (event, url) => {
    const isProtocol = AGREEMENT_REGEXP.test(url)
    if (isProtocol) {
      console.log('获取协议链接, 根据参数做各种事情')
      dialog.showMessageBox({
        type: 'info',
        message: 'Mac protocol 自定义协议打开',
        detail: `自定义协议链接:${url}`,
      })
    }
  })
  // window系统下唤醒应用会激活second-instance事件 它在ready执行之后才能被监听
  app.on('second-instance', (event, commandLine) => {
    // commandLine 是一个数组, 唤醒的链接作为数组的一个元素放在这里面
    commandLine.forEach(str => {
      if (AGREEMENT_REGEXP.test(str)) {
        console.log('获取协议链接, 根据参数做各种事情')
        dialog.showMessageBox({
          type: 'info',
          message: 'window protocol 自定义协议打开',
          detail: `自定义协议链接:${str}`,
        })
      }
    })
  })
}

// 在ready事件回调中监听自定义协议唤起
watchProtocol()
console.log('监听成功')

1.8 唤起应用执行回调示例

protocolWatch.gif

1.9 应用场景

  1. 单纯唤醒应用
    只需注册协议,系统会自动打开应用。
    表现:如果应用未打开将打开应用,如果应用已经打开应用将会激活应用窗口。
  2. 根据协议链接的参数进行各种操作
    如上面的弹窗演示, 在监听协议链接打开的时候,可以获取完整的协议链接
    我们可以根据协议链接来进行各种业务操作。
    比如跳转指定链接地址,比如判断是否登录再进行跳转,比如下载指定文件等。

1.10 一些其他API

app.removeAsDefaultProtocolClient(protocol) 删除注册的协议, 返回是否成功删除的Boolean

Mac: app.isDefaultProtocolClient(protocol) 当前程序是否为协议的处理程序。

app.getApplicationNameForProtocol(url) 获取该协议链接的应用处理程序

参数说明:

protocol 不包含:// 注册的协议名。

url 包含://

// 自定义协议的其他相关API
const { app } = require('electron')
const agreement = 'electron-playground-code' // 自定义协议名

console.log('自行注释,自由尝试')
const isApp = app.isDefaultProtocolClient(agreement)
console.log('当前程序是否为自定义协议的处理程序: ', isApp)

const AgreementAppName = app.getApplicationNameForProtocol(`${agreement}://`)
console.log('获取该自定义协议链接的应用处理程序的名字', AgreementAppName)

const isDelete = app.removeAsDefaultProtocolClient(agreement)
console.log('删除自定义协议', isDelete)

2. 自定义协议

注册自定义协议,拦截基于现有协议的请求,根据注册的自定义协议类型返回对应类型的数据。

我们可以自动的来使用所有的

在该项目中的代码地址: electron-playground/app/protocol, 可以运行项目调试一下看看效果。

2.1 protocol.registerSchemesAsPrivileged

将协议注册成标准的scheme, 方便后续调用。

注意: 它必须在ready事件加载之前调用,并且只能调用一次。

protocol.registerSchemesAsPrivileged([
  { scheme: 'myscheme', privileges: { bypassCSP: true } },
])

2.2 protocol.registerFileProtocol

拦截自定义协议的请求回调,重新处理后再请求路径。

示例

protocol.registerFileProtocol(
  'myscheme',
  (request, callback) => {
    // 拼接绝对路径的url
    const resolvePath = path.resolve(__dirname, '../../playground')
    let url = request.url.replace( `${myScheme}://`, '' )
    url = `${resolvePath}/${url}`
    return callback({ path: decodeURIComponent(url) })
  },
  error => {
    if (error) console.error('Failed to register protocol')
  },
)

PS: 在文档上提供了不同种类的加载API,这里只演示其中的一种。

2.3 使用方式

在html中使用自定义协议请求文件,即可自动拦截。

项目中的使用地址: electron-playground/playground/page/protocol/protocol.md

 <img src={"myscheme://page/protocol/wakeUp.jpg"} alt="wakeUp"/>

2.4 protocol其他API

protocol.unregisterProtocol(scheme) // 取消对自定义scheme的注册
protocol.isProtocolRegistered(scheme) // 自定义协议是否已经拦截
protocol.uninterceptProtocol(scheme) // 移除自定义协议的拦截器
// 各种用新的拦截器替换原有的拦截器
protocol.interceptFileProtocol(scheme, handler)
protocol.interceptStringProtocol(scheme, handler)
protocol.interceptBufferProtocol(scheme, handler)
protocol.interceptHttpProtocol(scheme, handler)
protocol.interceptStreamProtocol(scheme, handler)

对 Electron 感兴趣?请关注我们的开源项目 Electron Playground,带你极速上手 Electron。

我们每周五会精选一些有意思的文章和消息和大家分享,来掘金关注我们的 晓前端周刊


我们是好未来 · 晓黑板前端技术团队。
我们会经常与大家分享最新最酷的行业技术知识。
欢迎来 知乎掘金SegmentfaultCSDN简书开源中国博客园 关注我们。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容