在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)。
- 创建一个JSON文件(例如
- 注册原生消息主机:
- 在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
,XMLHttpRequest
或WebSocket
API连接到这个本地服务器。 - 通过HTTP请求/响应或WebSocket消息进行双向通信。
- 扩展接收到指令后操作浏览器,并将获取的内容通过HTTP/WebSocket发送回本地服务器。
-
优点: 使用标准的Web技术,可能更容易理解和实现。
-
缺点:
- 安全性:需要仔细处理认证和授权,防止其他本地进程或恶意网页访问该服务器。
- 端口冲突:需要确保所选端口未被其他应用占用。
- 防火墙:可能需要配置防火墙规则。
- 浏览器限制:浏览器对本地连接可能有额外的安全限制(例如,HTTPS要求、CORS策略)。
获取浏览器内容
无论使用哪种通信方式,获取浏览器内容的步骤通常涉及浏览器扩展:
- 本地应用发送请求: 本地应用通过已建立的通道(Native Messaging 或 HTTP/WebSocket)向扩展发送指令,指定要获取内容的页面URL和具体内容的选择器(如CSS选择器)或其他标识。
- 扩展处理请求: 扩展的后台脚本接收到指令。
- 执行内容脚本: 如果需要与页面DOM交互,后台脚本会通过
chrome.scripting.executeScript()
(MV3) 或类似API在目标标签页中注入并执行一个内容脚本 (Content Script)。 - 内容脚本获取数据: 内容脚本运行在网页的上下文中,可以使用标准的JavaScript DOM API(如
document.querySelector
,document.body.innerText
,window.getSelection().toString()
等)来查找元素、提取文本、HTML或其他所需信息。 - 数据传回: 内容脚本将获取到的数据通过消息传递发送回后台脚本。
- 发送回本地应用: 后台脚本再通过Native Messaging或HTTP/WebSocket将数据发送回本地应用程序。
总结
对于在Windows上从本地应用程序控制浏览器扩展并获取内容,原生消息传递 (Native Messaging) 是最健壮、安全且受浏览器厂商支持的标准方法。虽然初始设置可能复杂些,但它提供了可靠的双向通信通道。本地Web服务器是另一种选择,但需要更关注安全性和潜在的配置问题。
文章告一段落。如果你意犹未尽,渴望持续提升技术实力、拓宽视野,欢迎关注同名微信公众号“码觉客”。我们致力于分享高质量的技术干货、实战经验和前沿资讯,助你在技术的道路上走得更远。即刻搜索关注,解锁更多精彩!