在 Web 开发中,浏览器沙箱机制严格限制了网页对系统硬件的访问权限。然而,企业级应用(如硬件控制、设备管理)常需获取系统信息(如 MAC 地址、用户名)。本文介绍一种安全可靠的方案:Chrome Native Messaging,通过浏览器扩展与本地应用通信,实现系统级操作。
现代浏览器的隐私策略禁止网页直接调用系统 API,传统方案如修改浏览器内核或部署本地 HTTP 服务,存在兼容性差、部署复杂等问题。Native Messaging 机制 应运而生:
二、实现原理
Native Messaging 建立三层架构:
1.浏览器扩展:声明 nativeMessaging 权限,注册通信接口。
2.本地应用(Native Host):Python/Node.js/C++ 等编写的可执行程序,提供系统级能力。
3.消息通道:基于 stdin/stdout 传输 JSON 数据,消息长度限制为 1 MB。
消息传输流程:
浏览器扩展 → (JSON) → 本地应用 → (系统调用) → 返回结果
以 Python 脚本为例,改造自参考文档的 MAC 地址获取方案:
manifest.json
{
"manifest_version": 3,
"name": "Get System Info",
"permissions": ["nativeMessaging"],
"action": { "default_popup": "popup.html" }
}
popup.js文件
const hostName = 'com.example.getuserinfo';
const port = chrome.runtime.connectNative(hostName);
port.onMessage.addListener((response) => {
document.getElementById('username').innerText = response.username;
});
import sys
import struct
import getpass # 关键:获取系统用户名
def send_message(message):
sys.stdout.buffer.write(struct.pack('I', len(message)))
sys.stdout.write(message)
sys.stdout.flush()
def main():
username = getpass.getuser() # 获取当前用户名
send_message(f'{{"username": "{username}"}}')
if __name__ == "__main__":
main()
com.example.getuserinfo.json文件
{
"name": "com.example.getuserinfo",
"path": "/path/to/get_username.py",
"type": "stdio",
"allowed_origins": ["chrome-extension://EXTENSION_ID/"]
}
REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.google.chrome.example.echo" /ve /t REG_SZ /d "%~dp0com.google.chrome.example.echo-win.json" /f
浏览器开发者模式下加载解压的扩展程序。
3.权限控制
确保本地应用可执行权限。
参考文档中提到的通信模式同样适用:
短连接:chrome.runtime.sendMessage 单次请求。
长连接:chrome.runtime.connect 建立持久端口。
跨扩展通信:指定目标扩展 ID 发送消息。
消息通信关系示意图:
Chrome Native Messaging 为浏览器扩展提供了安全的系统级能力,平衡了功能需求与隐私保护。本文以获取用户名为例,展示了其核心实现逻辑,企业可根据需求扩展至硬件控制、文件读写等场景。
提示:完整代码参考 chrome-extensions-samples 中的 native-messaging 示例。
人有两个安慰自己的方法:一个是“等……后就好了”,另一个是“如果……就好了”,一个对未来,另一个则对过去。可事实证明,未来之事往往不可预料,而多半依旧不如意。人因为回不到过去,某种如果倒更是像对过去耍了个流氓,因为注定无法实现,自然可以随意假设。就比如:如果脚不受伤就好了,一定能减肥成功。