获取浏览器对象 (document 和 windows 对象)
获取浏览器对象 (document 和 windows 对象)
背景
Tauri 程序是否可以做到,获取当前聚焦的应用程序 (不是开发的 Tauri 程序本身,而是电脑上的其他程序。可能是浏览器软件,或包含了 webview/chrome内核且使用前端进行页面显示的其他程序) 中的浏览器对象?
- 如 document/window (指浏览器的windows) 对象?
- 或者尽可能地获取页面上的信息 (title、选中文本等,可能通过uia获取)?
- 如果无法直接获取,在允许安装浏览器扩展的前提,是否可以通过浏览器扩展暴露给该应用,从而获取到?
GPT 回答
by Gemini 3.1 Pro
作为一个 Tauri 程序,它的底层本质上是一个原生的桌面应用程序(通过 Rust 编写后端)。因此,它的能力边界与任何其他原生桌面程序(如使用 C++、C#、Go 编写的程序)是完全相同的。
针对你的三个问题,以下是详细的解答:
1. 能否直接获取其他应用程序的 document / window 对象?
绝对不能。
操作系统层面有严格的进程隔离(Process Isolation)机制,现代浏览器(以及包含了 Chromium 内核的 Electron/Tauri/WebView2 应用)更有自己极其严格的沙盒(Sandbox)安全机制。
一个进程绝对无法直接入侵另一个进程的内存去读取 JavaScript 的运行时对象(如 document 或 window)。
这是操作系统的安全底线,如果能做到,就等同于极其严重的安全漏洞(类似于恶意软件窃取网银密码)。
2. 能否通过系统 API (如 UIA) 获取页面信息 (标题、选中文本等)?
部分可以,但有局限性。 Tauri 可以通过 Rust 调用操作系统的底层 API 来实现这些功能:
- 获取窗口标题 (Title):
- 非常容易。 你可以使用 Rust 生态中的库(例如
active-win-pos-rs)来获取当前处焦点状态的窗口句柄及其标题。因为绝大多数浏览器(Chrome, Edge, Firefox 等)都会将当标签页的标题设置为操作系统的窗口标题,所以你可以直接读取到。
- 非常容易。 你可以使用 Rust 生态中的库(例如
- 获取选中文本:
可行,但方法分为“取巧”和“硬核”两种:- 取巧方案(模拟剪贴板,最通用):
- 当你的程序检测到用户按下了某个快捷键时,Tauri (Rust) 可以通过虚拟键盘模拟发送一个
Ctrl + C(Mac 上是Cmd + C) 的按键事件到当前焦点窗口,然后让你的程序立刻读取操作系统的剪贴板内容。这种方式几乎对所有软件都有效。可以使用enigo(模拟按键) 和arboard(读写剪贴板) 这类 Rust 库。
- 当你的程序检测到用户按下了某个快捷键时,Tauri (Rust) 可以通过虚拟键盘模拟发送一个
- 硬核方案(UI Automation / Accessibility):
- 在 Windows 上可以使用 UIAutomation (UIA),在 macOS 上可以使用 Accessibility API。
- 浏览器和大部分基于 Web 技术的应用为了支持屏幕阅读器(如残障人士使用的软件),会将一部分 DOM 结构暴露给操作系统的无障碍树(Accessibility Tree)。
- 你可以通过 Rust 调用这些操作系统的 UIA 接口去探测焦点元素的值和选中文本。
但这不是真实的 DOM,而是一棵简化版的 UI 树。开发难度很大,且对不同应用(有些前端框架没有做好无障碍适配)的兼容性极其不可靠。
- 取巧方案(模拟剪贴板,最通用):
3. 如果允许安装浏览器扩展,能否实现?
完美可行,这是最标准、最可靠的解决方案。
如果你的用户场景允许安装浏览器扩展 (Chrome Extension / Edge Addon),那么限制将彻底不复存在。因为浏览器扩展本身就运行在网页上下文,它可以轻易拿到 window、document、DOM 节点、选中文本等所有信息。
浏览器扩展将获取到的信息传递给你的 Tauri 桌面应用,通常有两种非常成熟的通信方式:
方案 A:通过本地服务器(最简单灵活,推荐)
- Tauri 侧: 在 Tauri 的 Rust 后端启动一个轻量级的本地 HTTP 或是 WebSocket 服务器(例如监听
127.0.0.1:18456,可以使用 Rust 的axum或warp库)。 - 扩展侧: 浏览器扩展(通过 Content Script 注入到当前页面,或者在 Background Service Worker 中),监听用户的操作(如选中文本、或者点击扩展图标)。获取到 DOM 信息后,通过普通的
fetch或WebSocket将数据发送给ws://127.0.0.1:18456。 - 结果: Tauri 收到数据,通过 Tauri 的事件机制推送到你的 Tauri 前端进行展示。
方案 B:通过 Native Messaging(原生消息传递,最安全正规)
Chrome/Edge 浏览器官方支持一种叫做 Native Messaging 的技术,专门用于浏览器扩展与系统上的本地原生程序通信。
- 你需要在用户的电脑上注册一个 Native Messaging Host(本质上是一个指向你 Tauri
.exe或.app二进制文件的 JSON 注册表/配置文件)。 - 浏览器扩展可以直接调用
chrome.runtime.connectNative('your.tauri.app.name')。 - 这会在后台唤起你的 Tauri 程序(或者与其通信),双方通过操作系统的标准输入/输出 (stdin/stdout) 进行 JSON 数据的实时双向传递。
总结建议
如果你需要的是通用性(不想让用户装插件),建议在 Rust 层使用 “获取当前活动窗口标题” + “模拟 Ctrl+C 读剪贴板” 的组合,这能覆盖 90% 的划词/取词需求。
如果你需要深度交互(精确知道是在哪个 DOM 节点、获取网页上下文),必须开发配套的浏览器扩展,并使用 WebSocket 或 Native Messaging 与 Tauri 后端通信。目前市面上类似 Notion Web Clipper、或者各种桌面端翻译软件的深度网页抓取功能,都是采用这种配套扩展的方式。