在Windows中如何通过本地应用程序调取浏览器插件操作浏览器并获取浏览器内容

2 阅读6分钟

在Windows中,通过本地应用程序(通常称为Native Application或Native Host)调用浏览器插件(Browser Extension)来操作浏览器并获取浏览器内容,最标准和推荐的方式是使用原生消息传递 (Native Messaging) 机制。

以下是实现这一目标的几种方法和关键步骤:

1. 原生消息传递 (Native Messaging)

这是 Chrome, Firefox, Edge 等主流浏览器官方推荐的方法,用于在浏览器扩展和本地应用程序之间安全地通信。

  • 工作原理:

    • 本地应用程序需要注册一个“原生消息主机 (Native Messaging Host)”。
    • 浏览器扩展通过特定的API (如 runtime.connectNative()runtime.sendNativeMessage()) 启动这个本地应用程序进程。
    • 浏览器与本地应用程序通过标准输入 (stdin) 和标准输出 (stdout) 进行通信,通常使用JSON格式传递消息。消息格式是特定的:消息内容是UTF-8编码的JSON字符串,前面有4个字节表示消息的长度(按本地字节顺序)。
    • 通信是双向的:扩展可以向本地应用发送指令,本地应用可以向扩展发送数据或结果。
  • 实现步骤:

    • 开发浏览器扩展:
      • 在扩展的 manifest.json 文件中声明 "nativeMessaging" 权限。
      • 使用 runtime.connectNative("your_native_host_name") 建立一个持久连接(返回一个 Port 对象),或者使用 runtime.sendNativeMessage() 发送一次性消息。持久连接通常更适合需要持续交互的场景。
      • 使用 port.postMessage(message) 向本地应用发送JSON消息。
      • 通过 port.onMessage.addListener(callback) 监听来自本地应用的消息。
      • 根据从本地应用接收到的指令,扩展可以使用其API(如 tabs, scripting)来操作浏览器(如切换标签、执行脚本)或获取内容(如通过内容脚本 content script 读取DOM)。
      • 将获取到的浏览器内容通过 port.postMessage() 发送回本地应用。
    • 开发本地应用程序 (Native Host):
      • 选择一种编程语言(如 C#, Python, Go, C++, Java 等)来编写本地应用程序。
      • 程序需要能够从标准输入 (stdin) 读取长度前缀的JSON消息,并向标准输出 (stdout) 写入长度前缀的JSON消息。
      • 解析来自扩展的指令(例如,“获取某个URL的特定元素内容”)。
      • 执行相应的本地操作(如果需要)。
      • 将结果(例如,获取到的内容或状态)封装成JSON消息发送回扩展。
    • 创建原生消息主机清单 (Native Host Manifest):
      • 创建一个JSON文件(例如 your_native_host_manifest.json)。
      • 文件内容包括:
        • name: 主机的唯一名称(扩展通过此名称连接)。只能包含小写字母数字、下划线和点。
        • description: 应用程序的描述。
        • path: 本地应用程序可执行文件 (.exe) 的路径。在Windows上可以是绝对路径,也可以是相对于清单文件所在目录的相对路径。
        • type: 通信类型,通常是 "stdio"
        • allowed_origins (Chrome/Edge) 或 allowed_extensions (Firefox): 一个包含允许连接此主机的扩展ID的数组。例如 ["chrome-extension://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/"] (Chrome/Edge) 或 ["your-extension-id@your-domain.com"] (Firefox)。
    • 注册原生消息主机:
      • 在Windows上,需要将清单文件的路径添加到注册表中。
      • 通常在 HKEY_CURRENT_USER\Software\Google\Chrome\NativeMessagingHosts\ (或对应Firefox/Edge的路径) 下创建一个以主机 name 命名的键。
      • 将该键的默认值设置为原生消息主机清单文件的完整路径。
      • 安装程序通常会负责创建这些注册表项。
  • 优点: 安全、标准、浏览器原生支持。

  • 缺点: 设置相对复杂,需要本地安装和注册表修改。

2. 本地Web服务器 (Localhost HTTP/WebSocket Server)

另一种方法是在本地应用程序中运行一个简单的HTTP或WebSocket服务器,监听一个本地端口(如 http://localhost:8080)。

  • 工作原理:

    • 本地应用程序启动一个监听特定端口(例如 8080)的HTTP或WebSocket服务器。
    • 浏览器扩展(需要相应的主机权限,如 <all_urls> 或特定于 http://localhost/* 的权限)通过标准的 fetch, XMLHttpRequestWebSocket API连接到这个本地服务器。
    • 通过HTTP请求/响应或WebSocket消息进行双向通信。
    • 扩展接收到指令后操作浏览器,并将获取的内容通过HTTP/WebSocket发送回本地服务器。
  • 优点: 使用标准的Web技术,可能更容易理解和实现。

  • 缺点:

    • 安全性:需要仔细处理认证和授权,防止其他本地进程或恶意网页访问该服务器。
    • 端口冲突:需要确保所选端口未被其他应用占用。
    • 防火墙:可能需要配置防火墙规则。
    • 浏览器限制:浏览器对本地连接可能有额外的安全限制(例如,HTTPS要求、CORS策略)。

获取浏览器内容

无论使用哪种通信方式,获取浏览器内容的步骤通常涉及浏览器扩展:

  1. 本地应用发送请求: 本地应用通过已建立的通道(Native Messaging 或 HTTP/WebSocket)向扩展发送指令,指定要获取内容的页面URL和具体内容的选择器(如CSS选择器)或其他标识。
  2. 扩展处理请求: 扩展的后台脚本接收到指令。
  3. 执行内容脚本: 如果需要与页面DOM交互,后台脚本会通过 chrome.scripting.executeScript() (MV3) 或类似API在目标标签页中注入并执行一个内容脚本 (Content Script)。
  4. 内容脚本获取数据: 内容脚本运行在网页的上下文中,可以使用标准的JavaScript DOM API(如 document.querySelector, document.body.innerText, window.getSelection().toString() 等)来查找元素、提取文本、HTML或其他所需信息。
  5. 数据传回: 内容脚本将获取到的数据通过消息传递发送回后台脚本。
  6. 发送回本地应用: 后台脚本再通过Native Messaging或HTTP/WebSocket将数据发送回本地应用程序。

总结

对于在Windows上从本地应用程序控制浏览器扩展并获取内容,原生消息传递 (Native Messaging) 是最健壮、安全且受浏览器厂商支持的标准方法。虽然初始设置可能复杂些,但它提供了可靠的双向通信通道。本地Web服务器是另一种选择,但需要更关注安全性和潜在的配置问题。


文章告一段落。如果你意犹未尽,渴望持续提升技术实力、拓宽视野,欢迎关注同名微信公众号“码觉客”。我们致力于分享高质量的技术干货、实战经验和前沿资讯,助你在技术的道路上走得更远。即刻搜索关注,解锁更多精彩!