首页
/ Web-Dev-For-Beginners 浏览器扩展项目实战:“Adopt an API”——选用外部 API 构建带本地存储的浏览器扩展

Web-Dev-For-Beginners 浏览器扩展项目实战:“Adopt an API”——选用外部 API 构建带本地存储的浏览器扩展

2026-09-06 15:18:47作者:房伟宁

本篇技术指南围绕 Web-Dev-For-Beginners 仓库“浏览器扩展项目(Part 2)”的配套作业 Adopt an API(日文版见 assignment.ja.md)展开:你将学会如何从公开 API 中选型、规划一个解决真实问题的浏览器扩展,并按“表单输入 + API 集成 + localStorage 持久化 + 异步请求 + 错误处理”的完整规格完成开发与交付。读完之后,你可以直接以仓库内 Carbon Trigger 参考实现为基准,独立完成一个可提交、可评分的 API 驱动型浏览器扩展。

Carbon Trigger 扩展运行效果:输入 API key 与地区后显示电网碳强度

在 Edge 中通过扩展面板加载未打包的 dist 目录

开发者工具 Application 标签下的 Local Storage 面板

作业定位:从静态表单走向“有记忆、会联网”的扩展

上一课(1-about-browsers)搭建了扩展的骨架与表单界面;本课 README 让扩展“活起来”——接入真实数据并记住用户配置。而 Adopt an API 作业正是这一能力的独立考核:作业要求你自选一个外部 API,构建一个解决真实问题或提供实用功能的浏览器扩展,API 选型可以小到“宠物照片不够看”(例如用 Dog CEO API 随机取狗图),也可以大一些,核心目标是让你独立完成一次完整的 API 集成练习。

这个作业的评分点不是“选了什么 API”,而是五个工程能力的落地程度:API 集成、代码质量、用户体验、Local Storage 使用、文档质量(详见后文完整 Rubric)。因此下文会先给出作业原文的完整规格,再对照仓库参考实现逐条印证。

四步工作流:选 API → 规划 → 构建 → 测试打磨

第一步:选择你的 API

作业给出的选型建议是:从公开免费 API 列表(public-apis,assignment.md 中链接)中挑选。面向初学者的推荐方向包括:

  • 娱乐:Dog CEO API——随机狗图片;
  • 天气:OpenWeatherMap——当前天气数据;
  • 名言:Quotable API——励志语录;
  • 新闻:NewsAPI——当前头条;
  • 趣味事实:Numbers API——数字冷知识。

选型标准可以从参考项目反推:仓库自己的 Carbon Trigger 扩展选用 CO2 Signal API,只依赖一个 auth-token 请求头加一个 countryCode 查询参数即可取数——无需复杂鉴权、单次请求即得结果的 API 最适合初学者(见“入门提示”第 1 条)。

第二步:写代码前先回答四个规划问题

作业要求在编码前明确回答:

  1. 你的扩展解决什么问题?
  2. 目标用户是谁?
  3. 你会在 local storage 里存什么数据?
  4. API 失败或触发限流时如何处理?

第 3、4 问直接对应参考实现的行为:solution/src/index.js 只持久化 apiKeyregion 两个键(第 72–80 行 setUpUser);第 62–67 行的 catch 分支则在请求失败时隐藏 loading、清空结果区并写入友好错误文案——这正是“如何处理 API 失败”的具体答案。

第三步:构建扩展(功能与代码双规格)

必需功能(Required Features),逐条来自 assignment.md

  • 表单输入所有必需的 API 参数;
  • API 集成并具备适当的错误处理;
  • 用 local storage 保存用户偏好或 API key;
  • 简洁、响应式的用户界面;
  • 加载状态与用户反馈。

代码要求(Code Requirements)

  • 使用现代 JavaScript(ES6+)特性;
  • API 调用使用 async/await
  • try/catch 做规范错误处理;
  • 添加解释代码的有意义注释;
  • 保持统一的代码格式。

第四步:测试与打磨

  • 用多种输入测试扩展;
  • 处理边界情况(断网、非法 API 响应);
  • 确保扩展在浏览器重启后仍正常工作(这验证 localStorage 持久化,而不是内存状态);
  • 添加用户友好的错误提示。

加分挑战(Bonus Challenges)

作业列出的进阶方向:

  • 接入多个 API 端点,扩展功能丰富度;
  • 实现数据缓存,减少 API 调用;
  • 为常用操作添加键盘快捷键;
  • 添加数据导出/导入功能;
  • 实现用户自定义选项。

这些挑战与主课 README 中的 GitHub Copilot Agent Challenge 呼应(重试退避、输入校验、带过期时间戳的缓存等),可作为交付后的迭代路线。

参考实现对照:Carbon Trigger 如何逐条满足规格

仓库提供了两版对照代码:start/src/index.js 是带编号占位符(//1//6)的骨架,solution/src/index.js 是完整实现。两者结构一致,适合逐段比对学习。

1. DOM 引用与事件监听:表单规格的落点

参考实现先集中捕获所有表单与结果元素(solution/src/index.js#L3-L15):.form-data 表单、.region-name.api-key 输入框、.errors.loading.result-container.carbon-usage.fossil-fuel.my-region.clear-btn。文件末尾(第 125–129 行)注册监听并启动应用:

form.addEventListener('submit', (e) => handleSubmit(e));
clearBtn.addEventListener('click', (e) => reset(e));

//start app
init();

handleSubmit 首先 e.preventDefault() 阻止页面刷新,再把输入值交给 setUpUser(第 82–86 行)——对应规格中“表单输入 API 参数”的要求。

2. Local Storage:持久化用户偏好

setUpUserinitsolution/src/index.js#L88-L123)实现了“记住设置、重启可用”:

// set up api key and region
const setUpUser = async (apiKey, region) => {
	localStorage.setItem('apiKey', apiKey);
	localStorage.setItem('region', region);
	loading.style.display = 'block';
	errors.textContent = '';
	clearBtn.style.display = 'block';
	//make initial call
	displayCarbonUsage(apiKey, region);
};

init() 在每次加载时检查 localStorage.getItem('apiKey')localStorage.getItem('region'):任一为 null 视为新用户,显示设置表单;否则隐藏表单、自动用已存凭据发起 API 调用并显示结果与清除按钮。reset() 只移除 region 键后重新 init()。这正是“浏览器重启后仍正常工作”这条测试项的实现依据。查看存储内容的方式:打开开发者工具(F12)→ Application 标签 → Local Storage 展开查看(见前文本地存储面板截图)。

⚠️ 与主课 README 相同的安全提示:把 API key 存在 localStorage 中,任何同页面 JavaScript 都可读取,仅适合学习场景;生产环境应改用服务端安全存储。

3. API 集成与错误处理:CO2 Signal 的完整调用链

参考实现用 axios 调用 CO2 Signal 的 v1/latest 端点(solution/src/index.js#L34-L68):params 携带 countryCode,请求头携带 auth-token 完成鉴权;拿到响应后先校验关键字段carbonIntensityfossilFuelPercentage 缺失则主动抛错),再 Math.floor 取整、更新 .my-region / .carbon-usage / .fossil-fuel 三个结果区,并隐藏 loading 与表单;catch 分支统一降级为友好提示:

	} catch (error) {
		console.warn('Data fetch failed:', error.message);
		loading.style.display = 'none';
		results.style.display = 'none';
		errors.textContent = 'Sorry, data unavailable for the selected region.';
	}

主课 README 中还给出了零依赖的 fetch 等价写法async 函数 + try/catch + response.ok 检查 + response.json() 解析),如果选择无构建依赖的 API(如 Dog CEO 这类免 key 接口),照该模式改写即可满足“API 集成 + 错误处理 + 加载状态”三项要求。

从源码结构看,displayCarbonUsage 内还会调用 calculateColor(CO2)(第 50 行),按碳强度值在 [0, 150, 600, 750, 800] 刻度中取最近档位映射到颜色,再通过 chrome.runtime.sendMessage({ action: 'updateIcon', ... }) 更新工具栏图标——这是下一课“动态图标”功能的预埋点,属于扩展而非本作业必需项。

评分 Rubric:交付物的五个维度

assignment.md 给出的完整评分表(90–100% 为模範级):

维度 模範(90–100%) 胜任(80–89%) 发展中(70–79%) 起步(60–69%)
API 集成 集成无瑕疵,错误处理与边界情况管理全面 集成成功,具备基础错误处理 可用但错误处理有限 集成存在重大问题
代码质量 干净、注释良好的现代 JS,遵循最佳实践 结构良好,注释适度 能运行但组织欠佳 质量差,注释极少
用户体验 界面精致,加载状态与用户反馈出色 界面良好,具备基础反馈 基本可用 体验差、界面令人困惑
Local Storage 运用娴熟,含数据校验与管理 关键功能正确实现 基础实现 使用极少或错误
文档 完备 README,含安装步骤与截图 覆盖大部分要求的文档 缺少部分细节的基础文档 文档差或完全缺失

对照该表,参考实现可以逐条定位证据:错误处理在 displayCarbonUsagecatch 分支;加载状态在 setUpUser/init 中对 .loading 的显隐切换;localStorage 管理在 init/reset 的读-写-删闭环;代码注释则遍布 solution/src/index.js 各函数。

交付清单与入门提示

提交要求(Submission Requirements)

  1. 一个可运行的浏览器扩展,成功集成为你所选的 API;
  2. 一份 README,说明:选择了哪个 API 及原因、如何安装与使用、是否需要 API key 或其他前置配置、扩展运行截图;
  3. 干净、注释充分的代码,遵循现代 JavaScript 实践。

入门提示(Getting Started Tips),共 5 条:

  1. 从简单开始:选不需要复杂鉴权的 API;
  2. 读文档:吃透所选 API 的端点与响应结构;
  3. 先规划 UI:编码前草图化扩展界面;
  4. 频繁测试:增量构建,每加一个功能就测一次;
  5. 默认会失败:始终假设 API 调用可能失败并提前规划。

本地运行:从仓库参考项目到浏览器加载

仓库的 start 目录给出了可复现的运行路径(package.json 声明 node >=18.0.0npm >=9.0.0):

npm install
npm run build

构建脚本即 package.json 中的 webpack(开发时可用 npm run watch 增量构建)。在 Edge/Chrome 中:扩展面板 → Load Unpacked → 选择构建产物 dist 目录即可加载;输入 CO2 Signal 的 API key(通过邮件在 co2signal.com 获取)与你的地区代码(参考 start/README.md 中给出的 Electricity Map 地区代码查询接口,如 US-NEISO),提交后工具栏圆点颜色即反映该地区电网碳强度。你也可以完全跳过参考项目,按“Adopt an API”的作业规格自选 API 从零实现——这正是作业考核的目标能力。

小结

  • 作业主体是 Adopt an API:四步流程(选 API → 规划 → 构建 → 测试打磨)+ 加分挑战 + 三件套交付(可运行扩展、README、规范代码)+ 五维 Rubric;
  • 必备技术清单:表单输入 API 参数、async/await + try/catch 的 API 集成、localStorage 持久化偏好/key、响应式 UI、加载状态与友好错误提示;
  • 仓库佐证:start/src/index.js 的六段骨架与 solution/src/index.js 的完整实现(init / reset / setUpUser / displayCarbonUsage / calculateColor)构成可逐段对照的参考答案;
  • 教学主线见 5-browser-extension/2-forms-browsers-local-storage/README.md,其中还列有 Geolocation、Notification、Web Storage 等浏览器内置 API 的课后挑战,可作为 API 选型后的第二成长路径。
登录后查看全文
热门项目推荐
相关项目推荐