本篇继 [[制作一款Chrome浏览器插件]],学习一下插件的构成
graph TD
%% 定义组件
Manifest[(manifest.json
配置文件)] subgraph "网页世界 (Web Page Context)" DOM[DOM / 网页 HTML] ContentScript[content.js
注入脚本] end subgraph "扩展内部世界 (Extension Context)" ServiceWorker[Service Worker / Background.js
后台逻辑 - 类似大脑] Popup[Popup / Options.js
前端交互界面] end subgraph "外部世界 (External)" AnkiConnect[AnkiConnect
127.0.0.1:8765] WebAPI[外部 API / 网页后端] end %% 定义交互关系 Manifest -.->|注册与配置| ContentScript Manifest -.->|生命周期管理| ServiceWorker Manifest -.->|定义 UI 入口| Popup DOM <-->|读写网页元素| ContentScript ContentScript <==>|Message Passing 通信| ServiceWorker Popup <==>|Message Passing 通信| ServiceWorker ContentScript -->|直接发送数据| AnkiConnect ServiceWorker -->|网络请求| WebAPI style Manifest fill:#f96,stroke:#333,stroke-width:2px style ContentScript fill:#4285f4,color:#fff style ServiceWorker fill:#34a853,color:#fff style Popup fill:#ea4335,color:#fff style AnkiConnect fill:#fff,stroke:#4285f4,stroke-dasharray: 5 5
配置文件)] subgraph "网页世界 (Web Page Context)" DOM[DOM / 网页 HTML] ContentScript[content.js
注入脚本] end subgraph "扩展内部世界 (Extension Context)" ServiceWorker[Service Worker / Background.js
后台逻辑 - 类似大脑] Popup[Popup / Options.js
前端交互界面] end subgraph "外部世界 (External)" AnkiConnect[AnkiConnect
127.0.0.1:8765] WebAPI[外部 API / 网页后端] end %% 定义交互关系 Manifest -.->|注册与配置| ContentScript Manifest -.->|生命周期管理| ServiceWorker Manifest -.->|定义 UI 入口| Popup DOM <-->|读写网页元素| ContentScript ContentScript <==>|Message Passing 通信| ServiceWorker Popup <==>|Message Passing 通信| ServiceWorker ContentScript -->|直接发送数据| AnkiConnect ServiceWorker -->|网络请求| WebAPI style Manifest fill:#f96,stroke:#333,stroke-width:2px style ContentScript fill:#4285f4,color:#fff style ServiceWorker fill:#34a853,color:#fff style Popup fill:#ea4335,color:#fff style AnkiConnect fill:#fff,stroke:#4285f4,stroke-dasharray: 5 5
关键组件解析
1. manifest.json:插件的“身份证”与“说明书”
这是每个插件必须有的文件。没有它,浏览器就不知道这个插件叫什么、能干什么。
- 核心功能:
- 元数据:定义插件名称、版本号、图标。
- 权限声明 (
permissions):告诉浏览器,“我要读取你的剪贴板”、“我要访问 Anki 的接口”。 - 运行规则 (
content_scripts):规定“在哪类网址下,运行哪段脚本”。
- 通俗比喻:它就像是一个工程图纸。它不直接干活,但它决定了谁去干活、去哪里干活。
2. content.js:注入网页的“特工”
这是我们前面制作的插件中“表格抓取”逻辑的地方。
3. 插件架构的四大支柱
- 核心功能:
- 操作 DOM:它能看到网页上的 HTML 结构(比如
<table>标签)。 - 注入 UI:它能在网页上画出你的“导入 Anki”按钮。
- 环境限制:它虽然住在网页里,但它和网页原本的 JS 代码是隔离的(这叫“隔离世界”),所以它不会破坏网页的功能,但也拿不到网页里的 JS 变量。
- 操作 DOM:它能看到网页上的 HTML 结构(比如
- 通俗比喻:它是一个派往敌国的间谍。它直接在“现场”(网页页面)活动,能看到现场发生的一切,并随时准备向家里汇报或在现场搞点小动作(注入按钮)。
| 组件 | 运行环境 | 主要任务 | 持续时间 |
|---|---|---|---|
| Manifest | 配置层 | 注册信息、定义权限 | 始终存在 |
| Content Script | 特定网页内 | 修改网页、抓取数据、监听点击 | 随网页关闭而结束 |
| Background (Service Worker) | 浏览器后台 | 处理跨标签任务、长连接、全局监听 | 自动唤起/休眠 |
| Popup / Options | 插件弹窗 | 用户设置界面、登录入口 | 仅在窗口打开时运行 |
4. 它们是如何“沟通”的?(Message Passing)
这是新手最容易困惑的地方:由于安全限制,这几个文件不能直接共享变量。
- 如果
content.js抓到了一个表格,想要告诉background.js去通知 Anki,它不能直接调用函数。 - 它必须通过
chrome.runtime.sendMessage发个“短信”。 background.js收到后,再执行相应逻辑。
5. 针对之前的需求,它是怎么跑起来的
- 加载阶段:浏览器读取
manifest.json,发现你在matches里写了gemini.google.com。 - 注入阶段:当你打开 Gemini 页面,浏览器自动把
content.js“塞”进这个页面里。 - 运行阶段:
content.js扫描 DOM 发现表格,在<table>上方插了一行 HTML 代码(你的控制条)。