惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
云风的 BLOG
云风的 BLOG
M
MIT News - Artificial intelligence
WordPress大学
WordPress大学
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
Secure Thoughts
博客园 - 【当耐特】
Know Your Adversary
Know Your Adversary
NISL@THU
NISL@THU
博客园 - 司徒正美
Last Week in AI
Last Week in AI
C
Cybersecurity and Infrastructure Security Agency CISA
P
Privacy & Cybersecurity Law Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
B
Blog
The GitHub Blog
The GitHub Blog
小众软件
小众软件
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Spread Privacy
Spread Privacy
Martin Fowler
Martin Fowler
博客园 - 叶小钗
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Tenable Blog
S
Securelist
博客园 - 三生石上(FineUI控件)
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Microsoft Security Blog
Microsoft Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
罗磊的独立博客
T
Threat Research - Cisco Blogs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
F
Full Disclosure
Cloudbric
Cloudbric
The Cloudflare Blog
Y
Y Combinator Blog
Hugging Face - Blog
Hugging Face - Blog
Microsoft Azure Blog
Microsoft Azure Blog
H
Hacker News: Front Page
腾讯CDC
L
Lohrmann on Cybersecurity
C
CERT Recently Published Vulnerability Notes
V2EX - 技术
V2EX - 技术
GbyAI
GbyAI
TaoSecurity Blog
TaoSecurity Blog
I
Intezer
The Last Watchdog
The Last Watchdog
G
GRAHAM CLULEY
Google Online Security Blog
Google Online Security Blog
T
The Blog of Author Tim Ferriss

蚊子的前端博客

微说 | 有的人觉得只要不考XX,一定能考好!-蚊子的前端博客 微说 | 春天来了-蚊子的前端博客 明天和意外不知道哪个先来-蚊子的前端博客 微说 | 既然错过了路口,就及时止损,重新规划路线上路-蚊子的前端博客 微说 | 2025年的出生人口数是792万-蚊子的前端博客 微说 | 工作年终总结,让写对接的接口的数量?-蚊子的前端博客 微说 | 温家宝:没有政治体制改革的成功 经济体制改革不可能进行到底-蚊子的前端博客 微说 | 违法犯罪了该不该被禁言?-蚊子的前端博客 微说 | 不明白为什么在推荐去俄罗斯旅游-蚊子的前端博客 微说 | 易中天论骗子-蚊子的前端博客 微说 | 一场大风吹散了秋天-蚊子的前端博客 微说 | 既要、又要、还要、更要!-蚊子的前端博客 又是一年的国庆雨季-蚊子的前端博客 微说 | 预估下2025年的出生人口数据-蚊子的前端博客 微说 | 可惜了我那些小时候的书本-蚊子的前端博客 微说 | 牛马有的是,驴不够了!-蚊子的前端博客 微说 | 能否有一条非户口也能高考的路-蚊子的前端博客 微说 | 小聊中医-蚊子的前端博客 微说 | 将要制作的一款新产品-蚊子的前端博客 微说 | 做人要有信-蚊子的前端博客 微说 | 好一个正义联盟-蚊子的前端博客 微说 | 都是见过吃过的主儿-蚊子的前端博客 微说 | 追求8小时工作制有错吗?-蚊子的前端博客 微说 | 如果尖锐的批评完全消失-蚊子的前端博客 微说 | 很好!-蚊子的前端博客 微说 | 封禁用户可以,但要告知具体原因-蚊子的前端博客 微说 | 面朝大海,春暖花开-蚊子的前端博客 微说 | 程序员的悲哀是什么?-蚊子的前端博客 微说 | 2025年出生人口的预测-蚊子的前端博客 前端在 LiveKit 中如何获取所有的参与者-蚊子的前端博客 在 Electron 中使用 LiveKit 实现屏幕共享-蚊子的前端博客 在 Electron 应用中,如何获取 Mac 的摄像头和麦克风权限-蚊子的前端博客 微说 | 不要总让台湾艺人表态-蚊子的前端博客 微说 | 他们总说要更开放-蚊子的前端博客 自己封装 uuid 踩的一个小坑-蚊子的前端博客 CKEditor5 光标在粘贴的图片下一行-蚊子的前端博客 软考出成绩了,没过-蚊子的前端博客 微说 | 也许有一天我们这个社会会进步-蚊子的前端博客 好久没有更新文章了-蚊子的前端博客 微说 | 中共中央关于进一步全面深化改革,推进中国式现代化的决定-蚊子的前端博客 微说 | 关于惩罚性赔偿-蚊子的前端博客 微说 | 生孩子是谁的事儿!-蚊子的前端博客 微说 | 给群众一些选择电视剧的空间-蚊子的前端博客 微说 | 活着-蚊子的前端博客 微说 | 借用睡前消息里面的一段话-蚊子的前端博客 微说 | 曾经梦寐以求的,现在却没了追求-蚊子的前端博客 微说 | 我小时候的那些书本-蚊子的前端博客 给博客添加了一个微说的功能-蚊子的前端博客 今年的双 11 很平静-蚊子的前端博客 微说 | 贪就是贪-蚊子的前端博客 微说 | 总有人说穿越小说为什么不发展工业和科技!-蚊子的前端博客 微说 | 花了很多时间和精力,-蚊子的前端博客 2025 年终于是增加了 2 天的假期-蚊子的前端博客 微说 | 这是我的第一条微说,-蚊子的前端博客 如何手写 Array 的 forEach 方法-蚊子的前端博客 看到聚美优品的没落,真是唏嘘-蚊子的前端博客 如何手写 Array 的 map 方法-蚊子的前端博客 秋意正浓时-蚊子的前端博客 收藏几个常用但访问比较慢的组件的官网网址-蚊子的前端博客 从 Axios 源码分析如何支持 fetch 方法的-蚊子的前端博客 1024,给博客评论区所有的头像戴上一顶可爱的帽子-蚊子的前端博客 使用 GitHub 搭建了一个静态博客-蚊子的前端博客 在 JavaScript 如何判断变量是否为空-蚊子的前端博客 我为什么还在坚持我的个人博客-蚊子的前端博客 不要再手动拼接 URL 参数,请使用 URLSearchParams-蚊子的前端博客 使用 NodeJs 向百度资源推送链接-蚊子的前端博客 工具链极度内卷,留给开发者的性能优化手段已经不多了-蚊子的前端博客 在 React 中显示多个标签,超出省略并可以 hover 显示更多-蚊子的前端博客 蚊子的前端博客:探索与分享前端技术的奇妙之旅-蚊子的前端博客 互联网程序员前景真的一片黑暗吗?-蚊子的前端博客 Deno2.0 正式发布,向 Node.js 兼容-蚊子的前端博客 React 请求数据别再使用 useEffect 和 useState,试试 SWR 吧!-蚊子的前端博客 React 的 useEffect 的一些使用场景和技巧-蚊子的前端博客 前端趣闻之 JavaScript 语言的诞生和发展-蚊子的前端博客 如何合并同一接口的相同参数的请求-蚊子的前端博客 百度搜索中关于蚊子前端博客的奇怪的检索数据-蚊子的前端博客 使用 React 实现 todo list 的 curd 操作-蚊子的前端博客 React 模板中为什么可以用逻辑与运算符-蚊子的前端博客 评论回复在一张表里的评论系统如何进行分页-蚊子的前端博客 React 组件多次调用时如何区分不同的 div 容器-蚊子的前端博客 安全赋值运算符,再也不用写 try-catch 了-蚊子的前端博客 使用 nextjs 重构我的个人博客-蚊子的前端博客 基于 gitlab 的 webhook 向飞书发通知-蚊子的前端博客 数字转换为更高量级单位的工具方法-蚊子的前端博客 如何避免旧请求的数据覆盖掉最新请求-蚊子的前端博客 JavaScript 中 toString 的冷知识-蚊子的前端博客 React 中 useState 和 useRef 与全局变量的区别-蚊子的前端博客 从面试官的角度分析下简历中存在的问题-蚊子的前端博客 使用 React 实现 6 个输入框的短信验证码功能-蚊子的前端博客 反驳那些要实时刷新页面的前端部署方案-蚊子的前端博客 JSON stringify 的一些不常见使用-蚊子的前端博客 JavaScript 中数组 Array 的常见操作-蚊子的前端博客 前端如何提升用户的交互体验-蚊子的前端博客 没有日的日期在iOS中报 Invalid Date 的探究-蚊子的前端博客 飞书很好,但还是没抗住-蚊子的前端博客 给 Antd 的 DatePicker 组件实现带有至今的功能-蚊子的前端博客 antd 的 InputNumber 输入框添加左右的加减按钮-蚊子的前端博客 给想进国央企的同学介绍一款招聘软件「国聘」-蚊子的前端博客 基于 React 和 antd 实现的图片裁剪压缩功能-蚊子的前端博客 uniapp 中 checkbox 中的 checked 不生效的方案-蚊子的前端博客
Electron 中使用 webview 中打开外部链接跳转问题-蚊子的前端博客
author · 2026-05-13 · via 蚊子的前端博客

最近遇到了一个比较棘手的问题,目前暂时还没有解决的方法,如果有同学曾经遇到过类似的问题,欢迎将解决方案分享出来。

我先简单描述一下问题:我目前使用的 Electron 版本是 34.x 版本,使用 webview 标签渲染外部链接。若该页面中使用了 window.open() 方法在新标签页中打开链接,在浏览器上是没有问题的,但在 electron 中是没有反应的。

1. 重写 window.open 方法 #

在咨询过 AI 后,是可以通过重写 window.open() 方法来实现的。有两种重写的方式,一种是在渲染层注入,另一种是在主进程注入。

渲染层注入:

webviewRef.current.addEventListener("dom-ready", () => {
  webviewRef.current.executeJavaScript(`
      // 强制覆盖,即使页面已经定义
      const originalOpen = window.open;
      window.open = function(url, name, features) {
          console.log('被拦截的 window.open:', url);
          // 主进程处理
          window.hivedoneApp.invoke("openUrl", { url });
          return null;
      };
      // 冻结这个属性,防止被再次修改
      Object.freeze(window.open);
  `);
});

主进程注入:

app.on("web-contents-created", (_, contents) => {
  contents
    .executeJavaScript(
      `
    // 保存原生 open
    // window._originalOpen = window.open; // 2

    // 永久重写
    window.open = function(url, target, features) {
      console.log('[重写] window.open:', url, Date.now());

      if (url && url.startsWith('http')) {
        // 主进程处理
        window.hivedoneApp.invoke("openUrl", { url });
      }

      // 阻止默认行为
      return null;
    };

    console.log('✅ 全局 window.open 重写成功!', Date.now());
  `,
    )
    .catch((err) => {});
});

这两种重写方式,都可以在 webview 中的页面生效。但若 webview 中加载的页面中还有一个 iframe,接着往下看。

2. webview 中嵌套 iframe 问题 #

但接下来就有两个问题一直没解决:

  1. 教程中都说 contents.setWindowOpenHandler() 可以拦截window.open()触发的行为,但实际测试发现,contents.setWindowOpenHandler() 并不能拦截 window.open() 触发的行为;目前还没找到原因;不过用重写 window.open() 方法倒也是可以解决。
  2. 若 webview 中加载页面中还有一个 iframe,iframe 中的 window.open() 是不会被重写的,若 iframe 中有 window.open() 触发的行为,直接就是无反应,同样的,iframe 中的 window.open() 方法也不会被 contents.setWindowOpenHandler() 拦截。

目前问题就卡住了,暂时还没有找到解决方法。

3. 更换成 WebContentView #

其实倒也是可以把 webview 替换成 WebContentView。但 WebContentView 是属于主进程创建的,层级太高,会遮挡住其他元素,导致其他元素无法正常显示。若页面中有一些弹窗、提示框等元素,就会有显示问题。

为了让这些弹窗能够正常显示,我可能还得要监控弹窗的显示和隐藏事件,然后再决定是隐藏还是显示 WebContentView。处理起来,也相当麻烦。我目前的方案是,监控页面元素的变动,然后判断网页中是否有弹窗、提示框等元素,若有,就隐藏 WebContentView,若无,就显示 WebContentView。

const observer = new MutationObserver(() => {
  const modals = Array.from(document.querySelectorAll(".ant-modal"));
  const popovers = Array.from(document.querySelectorAll(".ant-popover"));

  let isExisted =
    modals.filter((modal) => {
      return !modal.classList.contains("ant-modal-hidden") && !modal.classList.contains("ant-zoom-leave-active");
    }).length > 0;

  isExisted =
    isExisted ||
    popovers.filter((popover) => {
      return !popover.classList.contains("ant-popover-hidden");
    }).length > 0;

  // 若有弹窗、提示框等元素,就隐藏 WebContentView
  updateModalVisible(isExisted);
});
observer.observe(document.body, { childList: true, subtree: true, attributes: true });

4. 总结 #

用 webview 标签 和 WebContentView 两种方式都各有优劣,只能说更看重哪种交互方式,进行取舍。

当然,或许有什么更好的解决方案,欢迎分享出来。