目录
速记口诀 HTML 核心知识点 CSS 核心知识点 JavaScript 基础速查表 Manifest V2 vs V3 对比表 完整的最小插件代码模板 高频面试问答
一、速记口诀
HTML 是骨架,CSS 是衣裳,JS 让它动。 Manifest 三部分:BG、Content 和 Popup。 V3 弃持久,SW 被唤醒才干活。 改页面找 Content,发消息用 sendMessage。 权限分开 hosts 和 apis,调试打开扩展页。 异步记得 then 或 await,注入脚本改样式。
二、HTML 核心知识点
作用:HTML 是页面的骨架,定义网页有哪些内容(文字、图片、按钮等)及其结构顺序。
<!DOCTYPE html>:作用:告诉浏览器用 HTML5 标准解析页面,避免“怪异模式”。示例:<!DOCTYPE html><html>:作用:整个 HTML 文档的根容器。示例:<html lang="zh-CN"><head>:作用:存放元数据(标题、编码、样式表引用、SEO 信息),不直接显示在页面中。示例:<head><meta charset="UTF-8"></head><body>:作用:用户可见的页面内容(文字、图片、按钮等)都写在这里。示例:<body>...</body><div>:作用:块级容器,用于布局分组或包裹其他元素,本身无样式。示例:<div class="container">内容</div><span>:作用:行内容器,用于对文本中的一小部分单独设置样式或行为。示例:<span style="color:red;">警告</span><h1>~<h6>:作用:定义标题层级,<h1>最重要(一般一个页面只用一个),有助于 SEO 和可访问性。示例:<h1>主标题</h1><p>:作用:定义段落,自动在上下方添加间距。示例:<p>这是一段文字。</p><ul>/<ol>+<li>:作用:<ul>无序列表(圆点),<ol>有序列表(数字),<li>表示每一条。示例:<ul><li>苹果</li><li>香蕉</li></ul><a href="...":作用:超链接,点击跳转到另一个页面或锚点。示例:<a href="https://example.com">点击访问</a><img src="..." alt="...":作用:嵌入图片,src指定图片地址,alt在图片加载失败时显示的文字(也用于无障碍)。示例:<img src="logo.png" alt="网站Logo"><form>:作用:用户输入数据的容器,提交时可将数据发送到服务器。示例:<form action="/submit" method="post">...</form><input>:作用:输入字段,类型可以是文本、密码、复选框等。示例:<input type="text" name="username" placeholder="用户名"><button>:作用:可点击的按钮,常与 JavaScript 配合执行操作。示例:<button>提交</button><header>:作用:语义化标签,表示页面或区块的页眉(Logo、导航等)。示例:<header>...</header><footer>:作用:语义化标签,表示页面或区块的页脚(版权、链接等)。示例:<footer>© 2026</footer><section>:作用:表示文档中的一个独立章节(通常带标题)。示例:<section><h2>介绍</h2>...</section><article>:作用:表示独立可复用的内容(如博客文章、新闻条目)。示例:<article>...</article>
三、CSS 核心知识点
作用:CSS 控制页面的外观和布局——颜色、字体、位置、大小、响应式等。
内联样式:作用:直接作用于单个元素,优先级最高,但不便于复用和维护。示例: <div style="color:red;">文字</div>内部样式表( <style>):作用:定义当前页面的样式,可复用但只对本页面生效。示例:<style>.box { margin: 10px; }</style>外部样式表( <link>):作用:多页面共享同一份 CSS 文件,便于维护和缓存。示例:<link rel="stylesheet" href="style.css">标签选择器:作用:选中页面中所有同名标签,统一设置样式。示例: div { color: blue; }类选择器( .class):作用:选中所有拥有该 class 属性的元素,可复用。示例:.highlight { background: yellow; }ID 选择器( #id):作用:选中唯一的一个元素(ID 在页面中必须唯一)。示例:#header { font-size: 24px; }后代选择器(空格):作用:选中某元素内部的所有特定后代元素。示例: div p { color: gray; }(div 内的所有 p)并集选择器(逗号):作用:同时为多个选择器应用相同样式。示例: h1, h2, h3 { font-weight: bold; }盒模型( margin,border,padding,content):作用:定义元素占用的空间和间距。margin外边距(元素之间距离),border边框,padding内边距(内容与边框的距离)。示例:div { margin: 10px; padding: 5px; border: 1px solid black; }背景与颜色: background-color设置背景色,color设置文字颜色。示例:button { background-color: blue; color: white; }字体与文本: font-size文字大小,text-align水平对齐(left/center/right)。示例:p { font-size: 16px; text-align: center; }尺寸与边距: width/height设置宽高;margin/padding简写或单边。示例:.card { width: 200px; margin: 0 auto; }display:作用:决定元素的布局行为。block独占一行;inline不换行且不能设宽高;flex弹性布局;none隐藏元素。示例:nav { display: flex; }position:作用:控制元素的定位方式。relative相对原来位置偏移;absolute相对于最近的非 static 父元素定位;fixed相对于视口固定。示例:.tooltip { position: absolute; top: 10px; left: 0; }Flex 布局基础: display: flex创建弹性容器。justify-content控制主轴对齐(水平),align-items控制交叉轴对齐(垂直)。作用:轻松实现水平垂直居中、等分布局。示例:.container { display: flex; justify-content: center; align-items: center; }媒体查询( @media):作用:根据屏幕宽度、设备类型等条件应用不同样式,实现响应式。示例:@media (max-width: 600px) { body { font-size: 14px; } }
四、JavaScript 基础速查表
作用:JS 让页面变得“能动”——处理用户点击、修改页面内容、与插件 API 交互等。
x = 5 | let x = 5;const y = 10; | let 可变,const不可变(防止意外修改)。 | letconst无对应。 | |
print("hello") | console.log("hello"); | |||
def add(a, b): return a + b | function add(a, b) { return a + b; } | |||
const add = (a, b) => a + b; | this(插件开发常用)。 | |||
def greet(name="you"): | function greet(name = "you") { ... } | |||
{"name": "Alice"} | {name: "Alice"} | obj.name 或 obj["name"]。 | ||
[1, 2, 3] | [1, 2, 3] | |||
arr.append(4) | arr.push(4) | push | ||
arr.pop() | arr.pop() | |||
arr.index(2) | arr.indexOf(2) | |||
arr[1:3] | arr.slice(1, 3) | |||
map(callback, list)) | [1,2].map(x => x * 2) | |||
asyncio.create_task(foo()) | fetch(url).then(res => res.json()) | |||
data = await fetch_data() | const data = await fetch(url); | |||
try: ... except Exception as e: | try { ... } catch (e) { ... } | await 或 .catch()。 | ||
document.getElementById("id") | ||||
el.innerText = "新文本"el.style.backgroundColor = "red" | ||||
button.addEventListener("click", () => { ... }) | ||||
time.sleep(1) | setTimeout(() => { ... }, 1000) | |||
f"Hello {name}" | `Hello ${name}` | |||
a, b = [1, 2] | const [a, b] = [1, 2]; | |||
[1, *arr2] | const newArr = [1, ...arr2]; | ... 合并默认配置。 |
五、Manifest V2 vs V3 对比表
作用:知道 V2 到 V3 的变化,面试时能说出“为什么要改、影响什么、实际开发用哪个”。
background.scripts | background.service_worker | storage保存状态。 | ||
browser_actionpage_action | action | action。 | ||
permissions | permissions + host_permissions | host_permissions。 | ||
webRequest | declarativeNetRequest | |||
eval 和 new Function |
一句话总结:实际新项目用 V3;旧项目维护可能遇到 V2。面试时表示“理解差异,会按 V3 标准开发”。
六、完整的最小插件代码模板(修改当前页面背景色)
作用:展示一个可运行的 Chrome 插件(Manifest V3)的完整结构、每个文件的作用和消息流程。
文件结构
my-extension/├── manifest.json # 配置插件基本信息、权限、入口文件├── background.js # Service Worker,处理全局消息和跨页面任务├── content.js # 注入页面的脚本,可以操作 DOM├── popup.html # 点击图标后弹出的界面└── popup.js # popup 界面的交互逻辑1. manifest.json
{"manifest_version": 3,"name": "Bg Changer","version": "1.0","action": {"default_popup": "popup.html" },"background": {"service_worker": "background.js" },"content_scripts": [ {"matches": ["<all_urls>"],"js": ["content.js"] } ],"permissions": ["activeTab", "scripting"]}作用:
manifest.json是插件的“身份证”和“配置清单”。
manifest_version: 3:声明使用 V3 标准。action:定义插件图标,点击时弹出popup.html。background.service_worker:注册后台服务,处理消息。content_scripts:自动将content.js注入到所有匹配的页面(此处<all_urls>所有网址)。permissions:activeTab临时获取当前标签页权限;scripting允许动态执行脚本。
2. background.js(Service Worker)
// 监听来自 popup 的消息chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {if (request.action === "changeBg") {// 使用 .then() 风格处理异步 chrome.tabs.query({active: true, currentWindow: true}) .then((tabs) => {return chrome.scripting.executeScript({target: {tabId: tabs[0].id},func: (color) => { document.body.style.backgroundColor = color; },args: [request.color] }); }) .then(() => { sendResponse({status: "done"}); }) .catch(err =>console.error(err));return true; // 保持消息通道开放,等待异步 sendResponse }});// ---------- 如果用 async/await 写法(替换上面 if 块内的代码)----------/*if (request.action === "changeBg") { (async () => { try { const tabs = await chrome.tabs.query({active: true, currentWindow: true}); await chrome.scripting.executeScript({ target: {tabId: tabs[0].id}, func: (color) => { document.body.style.backgroundColor = color; }, args: [request.color] }); sendResponse({status: "done"}); } catch (err) { console.error(err); } })(); return true;}*/作用:
background.js在后台运行,负责接收 popup 发来的消息,并执行“修改当前页面背景色”的任务。
chrome.runtime.onMessage:监听消息。chrome.tabs.query:获取当前活动标签页。chrome.scripting.executeScript:在目标页面中执行函数,动态修改 DOM。return true:告知 Chrome 等待异步sendResponse。两种异步写法(.then/async-await)任选一种,面试时能说出即可。
3. content.js
// 作用:content script 可以直接访问页面 DOM。这里暴露一个全局函数供动态脚本调用。window.changeBgColor = (color) => {document.body.style.backgroundColor = color;};作用:
content.js运行在页面环境中,可以操作当前网页。但本例中,executeScript的func已经直接修改样式,此文件可留空。保留它展示另一种方式:预先定义函数。
4. popup.html
<!DOCTYPE html><html><head><style>button { margin: 10px; padding: 8px; }</style></head><body><buttonid="btnGray">变灰色</button><scriptsrc="popup.js"></script></body></html>作用:定义弹窗界面。只有一个按钮和引入的 JS 文件。样式简单,用于演示。
5. popup.js
const btn = document.getElementById("btnGray");// .then() 写法btn.addEventListener("click", () => { chrome.runtime.sendMessage({action: "changeBg", color: "gray"}) .then((response) => {console.log("背景已修改", response); }) .catch((err) =>console.error(err));});// ---------- async/await 写法(替换上面 addEventListener 的回调)----------/*btn.addEventListener("click", async () => { try { const response = await chrome.runtime.sendMessage({action: "changeBg", color: "gray"}); console.log("背景已修改", response); } catch (err) { console.error(err); }});*/作用:
popup.js绑定按钮点击事件,点击时向background.js发送消息(sendMessage),携带颜色值。background处理后返回响应,这里通过.then()或async/await接收。整个流程:用户点击弹窗按钮 → popup 发消息 → background 接收 → background 查询当前标签页 → background 注入脚本改背景色 → 回复 popup → popup 打印日志。
七、高频面试问答
问题 1:浏览器插件的整体架构是什么?各部件的作用?
回答要点:
Manifest 文件:配置插件名称、版本、权限、脚本入口等,是插件的“说明书”。 Background Service Worker:后台运行,处理全局事件(消息、网络、定时器等),不能操作 DOM。作用:跨页面协调、数据持久化、网络请求。 Content Script:注入到网页中的脚本,可以读取/修改页面 DOM。作用:与网页交互、提取数据、修改外观。 Popup:点击图标弹出的临时界面,通常用于用户交互(按钮、输入)。作用:提供快速操作入口。 消息传递:各部分通过 sendMessage和onMessage通信。作用:解耦组件,让 background 协调 content 和 popup。
问题 2:Content script 和 Background service worker 有什么区别?各自能做什么?
| 作用 | ||
| 运行环境 | ||
| 可用的 API | runtime),受同源限制 | |
| 生命周期 | ||
| 典型用途 |
回答示例:“Content script 负责动页面,background 负责动插件内部逻辑。比如修改背景色由 content 做,而监听网络请求由 background 做。”
问题 3:插件如何与网页通信?如何修改网页 DOM?
修改 DOM:通过 Content Script 直接操作( document.body.style.backgroundColor = "gray"),或使用chrome.scripting.executeScript动态注入代码。通信方式: 插件内部(popup ↔ background ↔ content): chrome.runtime.sendMessage/onMessage。作用:传递数据和指令。插件与网页:网页通过 window.postMessage与 content script 通信。作用:网页主动向插件发送数据。长期连接: chrome.runtime.connect建立 Port。作用:频繁双向通信,如聊天插件。
代码示例(同时展示两种异步写法):
// 发送消息(.then)chrome.runtime.sendMessage({cmd: "getData"}).then(res =>console.log(res));// 发送消息(async/await)const res = await chrome.runtime.sendMessage({cmd: "getData"});// 接收消息(需返回 true 表示异步响应)chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {console.log(msg); sendResponse({ok: true});returntrue;});作用:
sendMessage用于跨组件通信,返回 Promise。onMessage接收消息,return true表示会在未来调用sendResponse。
问题 4:请解释插件的权限机制(permissions vs host_permissions)。
permissions:作用:声明需要使用的 Chrome API 能力(如storage存储数据、tabs操作标签页、notifications发送通知)。host_permissions(V3 新增):作用:声明插件可以访问哪些网站的数据(如https://api.example.com/*)。访问跨域网站、在指定网站注入 content script、修改请求头都需要此权限。V2 中两者合并,用户安装时看到的是所有权限的集合。V3 分开让用户更清楚“插件能访问哪些网站”和“插件能调用哪些浏览器能力”。
示例:
{"permissions": ["storage", "activeTab"],"host_permissions": ["https://api.github.com/*"]}作用:插件只能访问 GitHub API 的数据,且可以读写插件自己的存储,但不能访问其他网站。
问题 5:如何调试一个浏览器插件?
进入管理页: chrome://extensions→ 开启“开发者模式”。Background Service Worker:在扩展卡片上点击“service worker”链接,打开独立 DevTools。作用:查看后台日志、断点调试、网络请求。 Content Script:在目标网页按 F12 → Sources → Content scripts 区域 → 选择扩展 ID。作用:调试注入到页面的脚本。 Popup:右键插件图标 → “检查弹出内容”。作用:调试弹窗页面的 JS 和 DOM。 常用方法: console.log输出变量、设置断点、查看网络请求(需在 background 或 popup 的 DevTools 中)。
作用:快速定位插件 bug,验证消息是否发送、DOM 是否修改成功。
八、关键 API 速查
.then() | async/await | ||
|---|---|---|---|
chrome.runtime.sendMessage | chrome.runtime.sendMessage({a:1}).then(r=>console.log(r)) | const res = await chrome.runtime.sendMessage({a:1}) | |
chrome.storage.local.set | chrome.storage.local.set({key:"val"}).then(()=>console.log("saved")) | await chrome.storage.local.set({key:"val"}) | |
chrome.storage.local.get | chrome.storage.local.get(["key"]).then(res=>console.log(res.key)) | const res = await chrome.storage.local.get(["key"]) | |
chrome.tabs.query | chrome.tabs.query({active:true}).then(tabs=>console.log(tabs[0].id)) | const tabs = await chrome.tabs.query({active:true}) | |
chrome.scripting.executeScript | chrome.scripting.executeScript({target:{tabId:id}, func:()=>alert("hi")}) | await chrome.scripting.executeScript({target:{tabId:id}, func:()=>alert("hi")}) |
夜雨聆风