基础知识
UI 主要提供以下几大功能:
- popup.html 弹窗式窗口
- side_panel.html 侧边栏
- 右击菜单
- 选项页(插件配置页面)
脚本:
- content.js(运行在网页。只能访问Dom,和页面的javascript环境是隔离的,不能相互访问)
- popup.js(运行在弹窗黑盒中)
- sidePanel.js(运行在侧边栏黑盒中)
- background.js(运行在Service worker)
- inject.js (运行在网页)
弹窗式窗口
第一步:配置popup.html
html 代码解读复制代码<html>
<head>
<title>hello worldtitle>
head>
<body>
<p>hello worldp>
<script src="./public/popup.js">script>
body>
html>
弹出式窗口使用的任何 Javascript代码
都必须位于单独的文件中,不能使用 script标签
。并且 Javascript代码
的作用域仅在弹窗式窗口中,与当前页面的 javascript 环境是 完全隔离
的。
第二步:配置manifest.json
json 代码解读复制代码{
"manifest_version": 3,
"name": "Test Extension",
"description": "Test Extension For dev",
"version": "1.0",
"action": {
"default_popup": "./popup.html",
"default_icon": "./assets/hello_extensions.png"
}
}
⚠️注意:同时设置弹窗(action)和 侧边栏(side_panel) 时候,弹窗失效
侧边栏窗口
第一步:配置popup.html
html代码解读复制代码
菜单
页面交互
popup.js/sidePanel.js 因为安全性问题,不能直接和 content.js
进行通信,必须要通过 background.js
通信传输路径:
pupup/sidePanel.js -> background.js -> content.js ⇋ inject.js
inject.js ⇋ content.js -> background.js -> popup/sidePanel.js
内容脚本(content.js)
运行在页面上,只能访问页面上的Dom,和页面的javascript环境是完全隔离的。需要通过chrome devtools进行调试(Sources/top/Cupshe Extension/public)
⚠️注意:修改后必须对页面进行刷新,否则不生效
manifest.json
json 代码解读复制代码{
"content_scripts": [{
"matches": ["" ],
"js": [
"scripts/content.js"
],
"css": ["style.css"],
}]
}
注入脚本(inject.js)
因为它被注入到页面中,而不是在 Chrome 扩展的沙箱环境中运行,它存在于页面的上下文执行中。content.js
使用 Dom 方法创建 script
标签将 inject.js
加载到页面中。
还需要在 manifest.json
文件中配置 web_accessible_resources。这样才能确保 inject.js 文件可以被网页访问和加载。
web_accessible_resources 是 Chrome 扩展中的一个配置项,指定哪些资源(如 JavaScript、CSS、图像等)可以被网页或内容脚本访问。默认情况下,Chrome 扩展的资源文件是封闭的,只有插件内部的脚本和页面可以直接访问。如果你想将某些文件(例如 inject.js)注入到网页中,就必须将其列入 web_accessible_resources。
content.js
js 代码解读复制代码const script = document.createElement('script');
script.src = chrome.runtime.getURL('inject.js'); // 获取 inject.js 的路径
(document.head || document.documentElement).appendChild(script); // 注入到页面中
script.onload = function() {
this.remove(); // 注入完成后删除 script 标签
};
manifest.json
json 代码解读复制代码{
"web_accessible_resources": [{
"resources": ["scripts/inject.js"],
"matches": ["" ]
}],
}
content.js 和 inject.js 的区别:
content.js 直接注入网页的DOM,可以访问并修改网页的 DOM 元素,但它不能直接与页面的 Javascript 变量、函数等交互。内容脚本被隔离在自己的环境中,并通过消息传递与其他插件组件(如后台脚本)进行通信。如果需要与 Javascript 直接交互,就需要借助 inject.js
后台脚本(background.js)
可以使用扩展程序的服务在后台监控浏览器事件worker。Service Worker 是一种特殊的 Javascript 环境,用于处理事件,并在不需要时终止。
在 manifest.json
文件中注册 Service Worker
json 代码解读复制代码{
"background": {
"service_worker": "background.js",
"type": "module", // 让 background.js 支持模块导入导出
}
}
chrome
runtime
- onInstalled
action
- onClicked: 点击插件图标时触发; 与manifest.json 中的 action.default_popup 是互斥
scripting(permissions开启 'scripting'权限)
- insertCSS 插入样式表。样式会在页面生效,但不会看到注入的css文件
- removeCSS 移除式表
- executeScript
sidePanel(permissions开启 'sidePanel'权限)
- setOptions chrome 安全机制,无法自动弹出。和manifest.json 中配置 side_panel 作用一样
tabs(permissions开启 'tabs'权限)
- onUpdated
长连接和一次性连接
在 Chrome 扩展开发中,长连接和一次性连接的区别主要体现在消息传递的持续性和用途。下面是对这两种连接方式的详细介绍:
一次性连接(短连接)
一次性连接使用 chrome.runtime.sendMessage 或 chrome.tabs.sendMessage,它用于短暂的通信,消息发送完毕后就断开连接。每次通信都需要重新建立连接。
适用场景:
- 发送单次请求和接收响应的场景,例如查询数据、触发某个事件等。
- 不需要持续的双向通信。
有两种方法可以实现短链接
- chrome.runtime.sendMessage anywhere
- chrome.tabs.sendMessage background -> content
实现: 发送端
js 代码解读复制代码chrome.runtime.sendMessage({ greeting: "hello" }, function(response) {
console.log("Response:", response);
});
接受端:
js 代码解读复制代码chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.greeting === "hello") {
sendResponse({ farewell: "goodbye" });
}
});
长连接
长连接使用 chrome.runtime.connect 和 port 对象来建立持久通信通道,允许多次消息的传递。连接一旦建立,双方可以通过这个通道进行持续的双向通信,直到明确关闭连接为止。
适用场景:
- 需要持续通信的场景,如监听某些状态、不断传输数据、WebSocket 类似的通信。
- 更复杂的交互,例如内容脚本和背景脚本之间的长时间通信。
实现: 建立连接和持续通信:
js 代码解读复制代码const port = chrome.runtime.connect({ name: "content-background" });
port.postMessage({ greeting: "hello" });
port.onMessage.addListener(function(msg) {
console.log("Received from background:", msg);
});
背景脚本端:
js 代码解读复制代码chrome.runtime.onConnect.addListener(function(port) {
console.log("Connection established:", port.name);
port.onMessage.addListener(function(msg) {
console.log("Message from content script:", msg);
if (msg.greeting === "hello") {
port.postMessage({ farewell: "goodbye" });
}
});
// 监听连接断开
port.onDisconnect.addListener(function() {
console.log("Connection closed.");
});
});
区别:
- 一次性连接:每次通信都需要重新发送消息,适合短时间的操作和事件驱动的行为。
- 长连接:连接一旦建立,通信通道会一直保持打开状态,直到明确关闭,适合需要频繁传递信息的场景。 总结
- 一次性连接 是基于请求-响应的模式,适合处理临时的通信需求。
- 长连接 适用于持续、频繁的通信,通常用来实现复杂的实时交互,如状态监听、持续数据传输等。
字段
字段 | 解释 |
---|---|
manifest_version | sdfsdf |
name | |
commands._execute_action | 当用户按下特定的快捷键时触发,等同于点击扩展图标 |
评论记录:
回复评论: