
浏览器扩展实战用 CO2 Signal API 构建 Carbon Trigger 碳排放强度提醒扩展【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners本文基于 Web-Dev-For-Beginners 课程仓库中浏览器扩展项目的完整实现solution 目录展开讲解如何用 JavaScript、axios 与 Webpack 构建一个运行在 Edge/Chrome 上的碳排放强度提醒扩展扩展通过 CO2 Signal API 实时读取指定区域的电力碳强度carbon intensity与化石燃料占比并在浏览器扩展栏中以“彩色圆点”的形式给出直观提示。读完本文你将掌握从环境准备、构建打包、浏览器加载到表单交互、localStorage 持久化、异步 API 调用与扩展图标动态更新的完整实战链路。扩展核心功能与工作方式Carbon Trigger 是一个典型的“小而专”的浏览器扩展它本质上是一个针对单一任务优化过的迷你网页应用。扩展向 CO2 Signal API 请求某区域的实时用电数据与碳强度把结果直接呈现在浏览器中帮助用户根据本地电力情况决定是否适合执行高耗能活动例如错开烘干机使用时段。在 5-browser-extension/README.md 中对这一设计有明确说明用户只需在扩展的表单中输入 API Key 与区域代码即可按需ad hoc查询本地用电强度。其“彩色圆点”图标系统的设计灵感来自面向加州排放数据的 Energy Lollipop 扩展。扩展的完整数据流如下用户在表单中输入 API Key 和区域代码并提交setUpUser将凭据写入localStorage并触发首次 API 请求displayCarbonUsage以 axios 请求 CO2 Signal API解析碳强度与化石燃料占比calculateColor依据碳强度数值计算对应的颜色并通过chrome.runtime.sendMessage通知后台更新工具栏图标界面中同时展示该区域的碳强度克/千瓦时与化石燃料发电占比百分比。环境准备Node.js 与 npm 要求构建该扩展需要先安装 npm。在 5-browser-extension/solution/package.json 中明确声明了运行环境约束{ engines: { npm: 9.0.0, node: 18.0.0 }, scripts: { test: echo \Error: no test specified\ exit 1, watch: webpack --watch, build: webpack }, devDependencies: { webpack: ^5.105.4, webpack-cli: ^5.1.4 }, dependencies: { axios: ^1.15.0 } }要点说明Node.js ≥ 18、npm ≥ 9这是 package.json 中engines字段规定的硬性门槛低于该版本可能导致依赖安装或 Webpack 构建失败axios ^1.15.0运行时唯一的第三方依赖用于发起对 CO2 Signal API 的 HTTP 请求webpack ^5.105.4 与 webpack-cli ^5.1.4作为开发依赖负责把src/index.js打包为浏览器可直接加载的产物npm run watch以监听模式持续构建改动源码后自动重新打包适合开发调试npm run build一次性生产构建产物输出到dist目录配合 Edge 的“加载解压缩的扩展”使用。安装与构建步骤将本仓库中 5-browser-extension/solution 目录的代码复制到本地文件夹后依次执行# 安装全部依赖根据 package-lock.json 精确还原版本 npm install # 使用 webpack 构建扩展 npm run build构建完成后工作区会生成dist目录其中包含打包后的index.js入口由 package.json 中的main: index.js指定。若在开发过程中需要反复验证改动可改用npm run watch保持监听构建。获取 API Key 与区域代码要让扩展真正工作需要准备两项凭据CO2 Signal API Key在 CO2 Signal 官网页面输入邮箱即可申请获取原文档说明通过邮件方式发放。API Key 会在请求时以auth-token请求头形式发送给服务端用于身份认证区域代码Zone Code对应 Electricity Map 的区域编号体系需从 API 的 zones 接口中查询例如波士顿地区使用的区域代码是US-NEISO。区域代码会作为countryCode查询参数传给 CO2 Signal API。在 5-browser-extension/solution/src/index.js 中可以看到实际请求的构造方式await axios .get(https://api.co2signal.com/v1/latest, { params: { countryCode: region }, headers: { auth-token: apiKey }, }) .then((response) { const data response?.data?.data; // ... });也就是说请求目标是 CO2 Signal 的latest端点认证方式为自定义请求头auth-token区域参数通过countryCode传递。在 Edge 中加载扩展构建完成后即可将扩展装入浏览器Edge 与 Chrome 操作一致点击浏览器右上角的“三点”菜单进入Extensions扩展面板开启“开发人员模式”选择Load Unpacked加载解压缩的扩展在弹出的文件选择框中打开项目下的dist目录扩展即被加载在扩展界面中输入 API Key 与区域代码后扩展栏中的彩色圆点会立即反映该区域的电力使用强度并给出适合执行哪些高耗能活动的提示。源码剖析完整实现的分层拆解完整实现集中在 5-browser-extension/solution/src/index.js 一个文件中逻辑可清晰划分为“DOM 引用 → 初始化 → 表单处理 → 用户配置 → API 调用 → 图标更新”六个环节。下面逐一展开。1. 捕获 DOM 元素引用代码开篇通过document.querySelector建立对所有需要操作的界面元素的引用solution/src/index.js// form fields const form document.querySelector(.form-data); const region document.querySelector(.region-name); const apiKey document.querySelector(.api-key); // results const errors document.querySelector(.errors); const loading document.querySelector(.loading); const results document.querySelector(.result-container); const usage document.querySelector(.carbon-usage); const fossilfuel document.querySelector(.fossil-fuel); const myregion document.querySelector(.my-region); const clearBtn document.querySelector(.clear-btn);这些引用分别对应课程第 2 课 2-forms-browsers-local-storage/README.md 中构建的 HTML 表单结构.form-data是输入表单.region-name与.api-key是两个输入框.loading、.errors与.result-container负责状态反馈.carbon-usage、.fossil-fuel、.my-region展示结果数据.clear-btn是重置按钮。2. 初始化逻辑localStorage 驱动的状态恢复init()函数是扩展的“导航系统”负责根据本地存储状态决定展示哪个界面solution/src/index.jsconst init async () { const storedApiKey localStorage.getItem(apiKey); const storedRegion localStorage.getItem(region); // 默认先将图标设为通用绿色 chrome.runtime.sendMessage({ action: updateIcon, value: { color: green }, }); if (storedApiKey null || storedRegion null) { // 首次使用展示设置表单 form.style.display block; results.style.display none; loading.style.display none; clearBtn.style.display none; errors.textContent ; } else { // 老用户自动加载已保存的凭据并立即请求数据 results.style.display none; form.style.display none; displayCarbonUsage(storedApiKey, storedRegion); clearBtn.style.display block; } };这里体现了两个关键设计localStorage 持久化扩展拥有独立于普通网页的隔离存储空间getItem/setItem以键值对方式读写当键不存在时getItem返回null这正是“首次使用”与“老用户”分支判断的依据启动即更新图标无论是否存在历史数据扩展启动时都会通过消息机制把图标重置为绿色保证状态一致。3. 表单提交与用户配置持久化表单提交与重置按钮分别绑定事件监听器solution/src/index.jsform.addEventListener(submit, (e) handleSubmit(e)); clearBtn.addEventListener(click, (e) reset(e)); // 启动应用 init();handleSubmit首先调用e.preventDefault()阻止浏览器默认的整页刷新行为然后提取两个输入框的值交给setUpUsersolution/src/index.jsconst setUpUser async (apiKey, region) { localStorage.setItem(apiKey, apiKey); localStorage.setItem(region, region); loading.style.display block; errors.textContent ; clearBtn.style.display block; // 立即发起首次数据请求 displayCarbonUsage(apiKey, region); };setUpUser完成三件事保存凭据到 localStorage、切换 UI 到加载中状态显示 loading、清空错误、露出重置按钮、立刻触发首次 API 请求。4. 核心数据请求axios 调用 CO2 Signal APIdisplayCarbonUsage是扩展的数据中枢solution/src/index.js完整代码如下const displayCarbonUsage async (apiKey, region) { try { await axios .get(https://api.co2signal.com/v1/latest, { params: { countryCode: region }, headers: { auth-token: apiKey }, }) .then((response) { const data response?.data?.data; // ✅ 使用前校验关键数据字段 if (data?.carbonIntensity null || data?.fossilFuelPercentage null) { throw new Error(Missing carbon intensity or fossil fuel data); } let CO2 Math.floor(data.carbonIntensity); calculateColor(CO2); loading.style.display none; form.style.display none; myregion.textContent region; usage.textContent Math.round(data.carbonIntensity) grams (grams C02 emitted per kilowatt hour); fossilfuel.textContent data.fossilFuelPercentage.toFixed(2) % (percentage of fossil fuels used to generate electricity); results.style.display block; }); } 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.; } };值得注意的实现细节请求认证通过headers: { auth-token: apiKey }传递密钥而非拼进 URL区域定位通过params: { countryCode: region }传入区域代码如US-NEISO数据校验在渲染前检查carbonIntensity与fossilFuelPercentage是否为空防止脏数据进入界面这是对“空数据导致 UI 异常”这一类错误的防御性处理异常兜底try/catch包裹整个请求流程失败时隐藏加载与结果区域并在.errors元素中输出“该区域数据不可用”的友好提示而非让扩展静默崩溃数据展示碳强度以整数克数展示克 CO₂/千瓦时化石燃料占比保留两位小数二者均写入对应 DOM 元素后显示结果容器。5. 颜色计算与工具栏图标动态更新calculateColor是扩展最具特色的部分solution/src/index.js它将连续的碳强度数值映射到离散的色阶calculateColor async (value) { let co2Scale [0, 150, 600, 750, 800]; let colors [#2AA364, #F5EB4D, #9E4229, #381D02, #381D02]; let closestNum co2Scale.sort((a, b) { return Math.abs(a - value) - Math.abs(b - value); })[0]; let num (element) element closestNum; let scaleIndex co2Scale.findIndex(num); let closestColor colors[scaleIndex]; chrome.runtime.sendMessage({ action: updateIcon, value: { color: closestColor } }); };算法逻辑如下预定义五档碳强度阈值[0, 150, 600, 750, 800]与五档颜色[#2AA364, #F5EB4D, #9E4229, #381D02, #381D02]绿 → 黄 → 橙 → 深棕越深代表碳强度越高通过排序取绝对值差找到与当前碳强度最接近的阈值用findIndex找到第一个大于该阈值的档位下标映射出对应颜色通过chrome.runtime.sendMessage({ action: updateIcon, value: { color } })将颜色信息发送给扩展的后台脚本由后台负责真正改写工具栏图标。这种“弹出式页面通过消息传递驱动后台更新图标”的架构是浏览器扩展的标准协作模式也是第 3 课 3-background-tasks-and-performance/README.md 重点讲解的内容扩展由内容脚本、弹出页面与后台脚本等多个上下文组成彼此通过消息传递通信。6. 重置逻辑reset函数让用户能够更换区域solution/src/index.jsconst reset async (e) { e.preventDefault(); // 仅清除区域保留 API Key localStorage.removeItem(region); init(); };它只移除region键而保留apiKey随后重新执行init()使扩展回到表单输入状态——用户无需重复填写 API Key 即可切换区域这是一个贴近真实使用场景的细节设计。从练习版到完整版的演进对照仓库同时提供了练习起点版本 5-browser-extension/start/src/index.js其中仅保留了带编号的注释骨架//1 // form fields // results divs //6 //call the API //5 //set up users api key and region //4 // handle form submission //3 initial checks //2 // set listeners and start app两版 package.json 与 solution/package.json 在依赖axios、webpack、webpack-cli和脚本build、watch上完全一致唯一区别是源码实现。对照阅读可以直观看到练习版给出了“捕获 DOM → 绑定监听 → 初始化 → 表单处理 → 配置用户 → 调用 API”的六步编号线索完整版则逐一落地为上述六个环节的真实代码。使用建议与安全注意事项API Key 的安全性本实现将 API Key 存储在localStorage中。正如第 2 课 2-forms-browsers-local-storage/README.md 所提醒的localStorage 中的数据可被页面内 JavaScript 读取存在一定的泄露风险对于学习型项目这一方案足够生产级应用应将敏感凭据放到服务端安全存储。区域代码的正确性区域代码必须使用 Electricity Map 体系的 zone code如US-NEISO输入错误会导致 API 返回错误此时界面会显示“数据不可用”的兜底提示。调试技巧可以在浏览器开发者工具F12的Application → Local Storage面板中查看扩展存储的apiKey与region键值扩展自身的 localStorage 与普通网页隔离调试时需在扩展上下文中查看。延伸学习路径本项目是 Web-Dev-For-Beginners 课程第 5 个模块的收官产物配套课程由浅入深覆盖了扩展开发全流程第 1 课认识浏览器与扩展基础第 2 课表单、浏览器与本地存储API 集成与持久化第 3 课后台任务与性能优化图标系统与消息传递结合完整实现源码 5-browser-extension/solution/src/index.js 阅读课程你不仅能复现一个可用的碳排放提醒扩展更能理解扩展上下文模型、异步 API 集成、持久化存储与动态图标更新这一整套浏览器扩展开发的核心技能。【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考