浏览器扩展实战:用 CO2 Signal API 构建 Carbon Trigger 碳排放强度提醒扩展

发布时间:2026/11/12 8:57:36

浏览器扩展实战:用 CO2 Signal API 构建 Carbon Trigger 碳排放强度提醒扩展 浏览器扩展实战用 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),仅供参考
延伸阅读

更多相关文章

2026/11/10 12:31:36

从ImageFolder到ResNet:小麦种子图像分类数据集实践指南

简介:小麦种子图像分类数据集面向计算机视觉学习者、研究者以及农业智能化项目开发者,提供约2000张已标注图片,覆盖4个品种类别,数据已经过预处理,可直接送入分类网络训练与验证,避免从零处理原始图像的重复…

2026/11/12 8:54:36

低压电工证免税怎么申请?含金量高不高值得考吗?

低压电工证免税怎么申请?含金量高不高值得考吗? 证书过期了不知道怎么复审延期,你不是一个人。最近在周口市从事低压电工工作的老张就遇到了这个问题,原本以为证件还能用几年,结果一查发现有效期只剩3个月了,慌得连工都干不下去了。低压电工证不仅是找…

2026/11/12 8:54:36

驻马店电工证办理点官方回应:电工证没考好,等于失业

驻马店电工证办理点官方回应:电工证没考好,等于失业 你有没有遇到过这样的情况:找了个电工的工作,结果被要求先考电工证?别急, 驻马店电工证办理点 最近 官方回应 了,从2024年起, 电工证不再只是“加分项”,而是“上岗门槛”…

2026/11/12 8:54:36

武都电工证培训机构含金量高不高?过期了怎么复审延期?

武都电工证培训机构含金量高不高?过期了怎么复审延期? 证书过期了不知道怎么复审延期?这事儿可不能拖, 武都电工证培训机构 的证书含金量摆在那儿,但一旦过期不处理,就等于白考。很多人在拿到证书后,忽略了复审的时间节点,结果到用证时才发现证件失…

2026/11/12 8:49:35

罗湖区电工证到期复审多少钱?学历不高也能搞定

罗湖区电工证到期复审多少钱?学历不高也能搞定 你是不是也担心,自己学历不高,罗湖区电工证到期复审怕报不上名?别担心,这事儿其实没你想的那么复杂,今天就来聊聊怎么搞清楚【罗湖区电工证到期复审多少钱】,以及整个流程到底怎么走。…

2026/11/11 12:42:59

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/12 0:04:01

工地太忙根本没时间复习考试?学习电工证到哪里学通过率揭秘

工地太忙根本没时间复习考试?学习电工证到哪里学通过率揭秘 工地太忙根本没时间复习考试?你不是一个人。作为一名在南阳卧龙区干了七八年市政公用工程的电工,我深知这个问题的现实性。电工证不仅是工作的“入场券”,更是职业发展的“通行证”,但备考过程…

2026/11/12 0:04:01

双流电工证考别怕挂科!郑州报考避坑指南全攻略

双流电工证考别怕挂科!郑州报考避坑指南全攻略 实操考试心里没底怕挂科?双流电工证考在郑州报名,很多人因为不了解流程、准备不充分,白白浪费时间和金钱。作为三门峡应届工程类毕业生,我也曾经历过这样的焦虑。今天就从零开始,手把手教你如何避开郑州报…

2026/11/12 0:04:01

之前考的证在外省能不能转过来 怎么报名考电工证培训价格多少

之前考的证在外省能不能转过来 怎么报名考电工证培训价格多少 之前考的证在外省能不能转过来?这个问题确实让不少准备换城市工作的朋友犯了难,尤其像电工证这种实操性很强的证书,很多人担心跨省后证书能不能继续用。其实,只要符合相关流程,是可以顺利转…

2026/11/11 20:27:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/10 10:29:37

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑