乐于分享
好东西不私藏

前端与浏览器插件技术 (面试速查手册)

前端与浏览器插件技术 (面试速查手册)

目录

  • 速记口诀
  • 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; }
  • 盒模型marginborderpaddingcontent):作用:定义元素占用的空间和间距。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 交互等。

知识点
Python 写法示例
JavaScript 写法示例
作用(解决什么问题)
说明
变量声明
x = 5let x = 5;const y = 10;
存储临时数据。let 可变,const不可变(防止意外修改)。
let
 类似 Python 普通变量;const无对应。
输出到控制台
print("hello")console.log("hello");
调试输出,查看变量值或程序执行情况。
面试可以说“用 console.log 调试插件”。
函数定义(普通)
def add(a, b): return a + bfunction add(a, b) { return a + b; }
封装可重复使用的逻辑代码块。
与 Python 类似。
箭头函数
无直接对应
const add = (a, b) => a + b;
更简洁的函数写法,且不绑定自己的 this(插件开发常用)。
可理解为“函数的简写形式”。
默认参数
def greet(name="you"):function greet(name = "you") { ... }
函数调用时若未传参,使用默认值。
与 Python 相同。
对象字面量(≈ 字典)
{"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()
移除并返回数组最后一个元素。
与 Python 相同。
数组查找索引
arr.index(2)arr.indexOf(2)
返回指定元素的索引,找不到返回 -1。
用于判断元素是否存在。
数组切片
arr[1:3]arr.slice(1, 3)
提取子数组,不修改原数组。
与 Python 相同。
回调函数
传函数对象(如map(callback, list)
[1,2].map(x => x * 2)
将函数作为参数传递给另一个函数,实现异步或高阶操作。
插件中大量用于异步 API。
Promise(异步)
asyncio.create_task(foo())fetch(url).then(res => res.json())
处理异步操作(网络请求、文件读取),避免回调地狱。
类比 Python asyncio。
async/await
data = await fetch_data()const data = await fetch(url);
以同步风格写异步代码,更易读。
插件中推荐使用。
try/catch
try: ... except Exception as e:try { ... } catch (e) { ... }
捕获并处理代码中的错误,防止程序崩溃。
异步错误需配合 await 或 .catch()
DOM 获取元素
document.getElementById("id") document.querySelector(".class")
从页面中选中某个 HTML 元素,后续才能修改它。
插件 content script 常用。
DOM 修改内容/样式
el.innerText = "新文本"
el.style.backgroundColor = "red"
动态改变页面文字、样式等。
插件实现“修改背景色”就靠这个。
事件监听
无(GUI 框架有绑定)
button.addEventListener("click", () => { ... })
响应用户操作(点击、键盘、鼠标移动等)。
插件 popup 按钮点击。
定时器(延时)
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 的变化,面试时能说出“为什么要改、影响什么、实际开发用哪个”。

特性
Manifest V2
Manifest V3
作用 / 为什么改动
面试要点
背景脚本
background.scripts
,可持久运行(后台常驻)
background.service_worker
,非持久,空闲时终止
节省系统资源,防止插件长时间占用内存。V3 需要开发者自己处理状态恢复。
V3 中全局变量会丢失,需用 storage保存状态。
Action 声明
browser_action
 或page_action
统一为 action
简化概念,合并两种按钮类型。
记住 V3 只用 action
权限
全部写在 permissions
拆分:permissions + host_permissions
让用户更清楚插件需要访问哪些网站的权限,提升透明度。
访问特定网站需声明 host_permissions
网络请求拦截
webRequest
(支持阻塞式修改/取消)
declarativeNetRequest
(声明式规则,不能动态修改请求体)
提升隐私和性能,防止插件窃取或篡改请求数据。
广告拦截插件受影响,能力减弱。
持久性
背景页常驻内存
Service Worker 无状态,休眠唤醒
减少内存占用,延长电池寿命。
V3 不能依赖全局变量缓存。
内容安全策略
较宽松
更严格,默认禁止 eval 和 new Function
防止 XSS 攻击,提升安全性。
避免使用动态代码执行。

一句话总结:实际新项目用 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> 所有网址)。
  • permissionsactiveTab 临时获取当前标签页权限;scripting 允许动态执行脚本。

2. background.js(Service Worker)

// 监听来自 popup 的消息chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {if (request.action === "changeBg") {// 使用 .then() 风格处理异步    chrome.tabs.query({activetruecurrentWindowtrue})      .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 { margin10pxpadding8px; }</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 有什么区别?各自能做什么?

对比项
Content Script
Background Service Worker
作用
操作页面 DOM,读取/修改网页内容
管理插件全局逻辑,处理异步事件
运行环境
目标网页中
插件独立后台,无 DOM
可用的 API
部分 Chrome API(如 runtime),受同源限制
绝大部分 Chrome API
生命周期
随页面刷新/关闭而销毁
非持久,空闲时终止,被事件唤醒
典型用途
修改页面样式、注入按钮、爬取数据
跨标签页通信、网络拦截、定时任务

回答示例:“Content script 负责动页面,background 负责动插件内部逻辑。比如修改背景色由 content 做,而监听网络请求由 background 做。”

问题 3:插件如何与网页通信?如何修改网页 DOM?

  • 修改 DOM:通过 Content Script 直接操作(document.body.style.backgroundColor = "gray"),或使用 chrome.scripting.executeScript 动态注入代码。
  • 通信方式
    1. 插件内部(popup ↔ background ↔ content):chrome.runtime.sendMessage / onMessage。作用:传递数据和指令。
    2. 插件与网页:网页通过 window.postMessage 与 content script 通信。作用:网页主动向插件发送数据。
    3. 长期连接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({oktrue});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 速查

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
向指定标签页注入 JavaScript 代码并执行,用于动态操作页面 DOM。
chrome.scripting.executeScript({target:{tabId:id}, func:()=>alert("hi")})await chrome.scripting.executeScript({target:{tabId:id}, func:()=>alert("hi")})