You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron自定义协议未注册时调用报错,如何检测处理?

自定义协议唤起Electron应用:未安装时避免错误弹窗并检测状态

问题背景

通过自定义协议xyz://唤起自研Electron应用时,应用已安装可正常唤起;但未安装时,浏览器会弹出“Module is not found”错误弹窗,且try-catch无法拦截该浏览器级错误。需求是提前检测协议是否注册(即应用是否安装),未注册时显示提示或禁用唤起按钮。

已配置信息:

  • Electron的package.json协议配置:
"protocols": {
    "name": "electron-deep-linking",
    "schemes": [
      "xyz"
    ]
  },
  • Electron端协议注册代码:
app.setAsDefaultProtocolClient('xyz');
  • 原网页唤起代码:
window.location.assign("xyz://");

解决方案

浏览器没有直接检测自定义协议注册状态的API,可通过间接判断浏览器行为实现检测:

方法1:基于页面焦点变化的检测

当协议可被处理时,唤起应用会使浏览器失去焦点;若协议未注册,浏览器焦点不会变化。结合定时器判断:

function openElectronApp() {
  const start = Date.now();
  // 尝试唤起应用
  window.location.assign('xyz://');

  // 500ms后检测焦点状态
  setTimeout(() => {
    // 若时间差小于1000ms且页面仍处于焦点,判定协议未注册
    if (Date.now() - start < 1000 && document.hasFocus()) {
      alert('应用未安装,请先安装后重试');
      // 禁用唤起按钮示例:
      // document.getElementById('your-button-id').disabled = true;
    }
  }, 500);
}

方法2:iframe加载+错误回调+定时器兜底

创建隐藏iframe加载协议,未注册时会触发onerror事件,同时结合页面焦点变化和定时器避免误判:

function checkAndLaunchApp() {
  const iframe = document.createElement('iframe');
  iframe.style.display = 'none';
  iframe.src = 'xyz://';
  let isAppLaunched = false;

  // 唤起成功时页面失焦,标记为已启动
  window.addEventListener('blur', () => {
    isAppLaunched = true;
  }, { once: true });

  // 加载错误且未启动应用,判定未安装
  iframe.onerror = () => {
    if (!isAppLaunched) {
      alert('应用未安装,请先安装后重试');
    }
    document.body.removeChild(iframe);
  };

  // 1秒后兜底判断
  setTimeout(() => {
    if (!isAppLaunched) {
      alert('应用未安装,请先安装后重试');
    }
    document.body.removeChild(iframe);
  }, 1000);

  document.body.appendChild(iframe);
}

注意事项

  • 定时器时长可根据系统响应速度调整(推荐500-1000ms),避免因系统卡顿导致误判。
  • 部分浏览器可能拦截自定义协议唤起,可配合引导用户允许相关操作。
  • 若需页面加载时就检测状态,可在DOMContentLoaded事件中调用上述检测逻辑,提前设置按钮禁用状态。

内容的提问来源于stack exchange,提问作者Himesh Aadeshara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 00:20:20