尧图精选

Web-Dev-For-Beginners 浏览器扩展实战(二):调用 CO2 Signal API 与 LocalStorage 持久化,构建碳足迹追踪扩展

🕒 发布时间:2026/9/10 9:34:01 📁 来源:尧图网络
Web-Dev-For-Beginners 浏览器扩展实战二调用 CO2 Signal API 与 LocalStorage 持久化构建碳足迹追踪扩展【免费下载链接】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 课程“浏览器扩展”模块的第二部分目标是把上一课搭建的静态碳足迹表单扩展改造成一个真正动态的工具通过调用 CO2 Signal API 获取指定地区电网的实时碳强度数据并利用 LocalStorage 记住用户的 API 密钥与地区设置。读完本篇你将掌握 DOM 元素引用、事件监听、async/await异步网络请求、try/catch错误处理与浏览器本地存储的完整实战链路最终得到一个可安装运行的碳足迹追踪浏览器扩展。课程定位从静态表单到动态扩展在上一课中你已经完成了浏览器扩展的界面部分——一个外观不错的配置表单但它本质上还是“静态”的无法与真实世界交互。本课要做两件核心的事接入真实数据让扩展通过 HTTP 请求访问外部 API获取某个国家/地区电网的实时碳强度数据grams CO₂ / kWh与化石燃料发电占比。赋予记忆用localStorage把用户的 API 密钥和地区代码保存在浏览器中让扩展在下次打开时能自动恢复用户设置而不是每次重新输入。这正是本课程项目“Carbon Trigger”碳触发器扩展的价值场景用户输入 API 密钥和地区代码后即可随时查看本地区当前电力碳强度从而判断何时适合运行烘干机这类高耗电活动例如在电力较清洁的时段使用。仓库中本课的代码骨架位于 5-browser-extension/start/src/index.js以编号注释//1到//6标出了你需要在哪些位置补全代码完整实现位于 5-browser-extension/solution/src/index.js可作为对照参考。捕获 DOM 元素为 JavaScript 建立界面引用在 JavaScript 能操控界面之前必须先拿到具体 HTML 元素的引用。仓库中的表单结构定义了以下关键 CSS 类.form-data表单、.region-name地区输入框、.api-keyAPI 密钥输入框以及结果展示区域.result-container、.carbon-usage、.fossil-fuel、.my-region外加交互辅助元素.loading加载指示、.errors错误信息、.clear-btn清除按钮。在 5-browser-extension/start/src/index.js 的//1位置补全如下代码用document.querySelector()按 CSS 类选择器逐一捕获引用// 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);这段代码做了四件事用document.querySelector()配合 CSS 类选择器捕获表单与输入框元素为地区名与 API 密钥创建输入框引用建立与碳数据结果展示元素的连接碳强度、化石燃料占比、地区名将每个元素引用存入const变量供代码后续复用。全部使用const声明因为引用一经建立就不会重新赋值这也符合现代 JavaScript 的最佳实践。解决方案源码 5-browser-extension/solution/src/index.js 中采用了完全一致的捕获方式可见这是贯穿项目的标准模式。事件驱动添加 submit 与 click 监听器拿到元素引用后下一步是让扩展响应用户操作。在 5-browser-extension/start/src/index.js 的//2位置添加监听器并启动应用form.addEventListener(submit, (e) handleSubmit(e)); clearBtn.addEventListener(click, (e) reset(e)); init();要点解析为表单挂载submit监听器用户按下 Enter 或点击提交按钮时触发为清除按钮挂载click监听器用于重置表单事件对象(e)被传递给处理函数供其调用e.preventDefault()等方法做精细控制立即调用init()在扩展启动时设置初始状态。这里使用了 ES6 箭头函数简写语法比传统的function表达式更简洁两者功能等价。完整实现见 5-browser-extension/solution/src/index.js。自测如果忘了在表单提交处理中调用e.preventDefault()会怎样答案是页面会被重新加载所有 JavaScript 状态全部丢失用户输入也会丢失体验被彻底打断。这正是现代单页式扩展必须拦截默认提交行为的原因。记忆功能理解浏览器 LocalStorage本课的数据持久化核心是localStorage。它有以下关键特性特性说明持久性数据在浏览器会话之间保留关闭浏览器、重启电脑甚至浏览器崩溃后依然存在区别于 sessionStorage数据模型以“键-值对”存储通过getItem()/setItem()/removeItem()操作缺省返回键不存在时getItem()返回null访问速度本地即时访问无网络延迟隔离性每个浏览器扩展拥有独立的LocalStorage与普通网页隔离避免安全冲突一个重要的隔离细节扩展的 LocalStorage 与访问普通网站时使用的 LocalStorage 是彼此独立的存储空间这保证了扩展数据的私密性与安全性。你可以打开浏览器开发者工具F12切到Application应用程序标签页展开Local Storage分支查看扩展保存的数据界面如下图所示⚠️安全提醒在生产级应用中把 API 密钥存进 LocalStorage 存在安全风险——任何能执行 JavaScript 的脚本都有可能读到这些数据。本课为教学目的采用该方案是可行的但真实应用应对敏感凭据使用安全的服务端存储。初始状态管理init() 与 reset()init()是扩展的“导航系统”启动时检查 LocalStorage 中是否已有上次保存的凭据据此决定显示配置表单还是直接加载结果。在 5-browser-extension/start/src/index.js 的//3位置实现function init() { // Check if user has previously saved API credentials const storedApiKey localStorage.getItem(apiKey); const storedRegion localStorage.getItem(regionName); // Set extension icon to generic green (placeholder for future lesson) // TODO: Implement icon update in next lesson if (storedApiKey null || storedRegion null) { // First-time user: show the setup form form.style.display block; results.style.display none; loading.style.display none; clearBtn.style.display none; errors.textContent ; } else { // Returning user: load their saved data automatically displayCarbonUsage(storedApiKey, storedRegion); results.style.display none; form.style.display none; clearBtn.style.display block; } } function reset(e) { e.preventDefault(); // Clear stored region to allow user to choose a new location localStorage.removeItem(regionName); // Restart the initialization process init(); }逻辑拆解从 LocalStorage 读取apiKey与regionName两个键任一为null说明是新用户显示配置表单隐藏结果、加载指示与清除按钮清空错误信息两个都有值说明是回访用户直接调用displayCarbonUsage()自动拉取数据隐藏表单并显示清除按钮reset(e)先preventDefault()再移除regionName键最后重新执行init()回到首次配置状态。这套“检查存储 → 分支渲染”的状态机也反映在课程文档的状态图中扩展启动 → 检查存储 →无数据显示表单 → 用户输入 → 保存 → 拉取 API → 显示结果 →有数据直接加载 → 拉取 API → 显示结果 → 用户点清除 → 删除存储 → 回到配置。仓库解决方案在 5-browser-extension/solution/src/index.js 中的init()/reset()实现了同样的状态管理并额外通过chrome.runtime.sendMessage把扩展图标先设置为通用绿色这是下一课“背景任务与性能”将完整实现的图标动态变色功能的前置动作。处理表单提交handleSubmit 与 setUpUser拦截提交handleSubmit浏览器默认会在表单提交后刷新页面我们要拦截这个行为以获得流畅的单页体验。在 5-browser-extension/start/src/index.js 的//4位置实现function handleSubmit(e) { e.preventDefault(); setUpUser(apiKey.value, region.value); }e.preventDefault()阻止页面重载从apiKey.value与region.value提取用户输入把表单数据交给setUpUser()继续处理。另外表单输入框带有required属性浏览器会在调用本函数前自动校验用户是否已填写 API 密钥和地区未填写则不会触发提交。保存偏好并首拉数据setUpUsersetUpUser负责把用户凭据持久化并启动首次 API 调用在 5-browser-extension/start/src/index.js 的//5位置实现function setUpUser(apiKey, regionName) { // Save user credentials for future sessions localStorage.setItem(apiKey, apiKey); localStorage.setItem(regionName, regionName); // Update UI to show loading state loading.style.display block; errors.textContent ; clearBtn.style.display block; // Fetch carbon usage data with users credentials displayCarbonUsage(apiKey, regionName); }一步步看把 API 密钥与地区名写入 LocalStorage供未来会话使用显示加载指示器告知用户数据正在获取清空历史错误信息显示清除按钮方便用户日后重置设置用用户凭据发起 API 调用获取真实碳数据。该函数把“数据持久化”和“界面状态更新”协调在一个动作里实现了从配置到结果的平滑过渡。仓库解决方案 5-browser-extension/solution/src/index.js 中该函数被声明为async为后续调用链预留异步能力核心逻辑与课程一致只是存储键名简化为region。接入真实数据displayCarbonUsage 调用 APIREST API 基本概念API应用程序编程接口是不同应用之间通信的通道。本课使用的是 CO2 Signal API它提供全球电网的实时碳强度数据。REST 风格 API 的核心约定REST 即 Representational State Transfer表述性状态转移使用标准 HTTP 方法GET、POST、PUT、DELETE操作数据返回可预测的格式通常是 JSON通过一致的 URL 端点提供不同类型的请求。本课请求的参数构成是HTTP 方法GET、请求头携带auth-token、查询参数携带countryCode地区代码响应体则包含碳强度、化石燃料百分比与时间戳。理解异步 JavaScript调用外部 API 属于网络 I/O如果同步阻塞整个扩展会像空管系统等待一架飞机应答一样“冻结”。async/await的价值正在于此数据加载期间扩展保持响应网络请求期间其他代码可继续执行相比传统回调写法可读性大幅提升能为网络错误提供优雅的捕获路径。实现 fetch async/await在 5-browser-extension/start/src/index.js 的//6位置实现数据获取与展示函数// Modern fetch API approach (no external dependencies needed) async function displayCarbonUsage(apiKey, region) { try { // Fetch carbon intensity data from CO2 Signal API const response await fetch(https://api.co2signal.com/v1/latest, { method: GET, headers: { auth-token: apiKey, Content-Type: application/json }, // Add query parameters for the specific region ...new URLSearchParams({ countryCode: region }) { url: https://api.co2signal.com/v1/latest?countryCode${region} } }); // Check if the API request was successful if (!response.ok) { throw new Error(API request failed: ${response.status}); } const data await response.json(); const carbonData data.data; // Calculate rounded carbon intensity value const carbonIntensity Math.round(carbonData.carbonIntensity); // Update the user interface with fetched data loading.style.display none; form.style.display none; myregion.textContent region.toUpperCase(); usage.textContent ${carbonIntensity} grams (grams CO₂ emitted per kilowatt hour); fossilfuel.textContent ${carbonData.fossilFuelPercentage.toFixed(2)}% (percentage of fossil fuels used to generate electricity); results.style.display block; // TODO: calculateColor(carbonIntensity) - implement in next lesson } catch (error) { console.error(Error fetching carbon data:, error); // Show user-friendly error message loading.style.display none; results.style.display none; errors.textContent Sorry, we couldn\t fetch data for that region. Please check your API key and region code.; } }这段代码展示了现代前端开发的多个核心实践使用原生fetch()API无需引入 Axios 等外部依赖代码更轻量仓库解决方案版本 5-browser-extension/solution/src/index.js 则演示了用 axios 实现同一请求的等价写法两者可互相印证通过response.ok做早期错误检查在解析前拦截失败的请求HTTP 非 2xx 状态用async/await让异步流程读起来像同步代码通过auth-token请求头完成 CO2 Signal API 鉴权解析 JSON 响应并提取data.data.carbonIntensity、data.data.fossilFuelPercentage用Math.round()四舍五入碳强度用toFixed(2)格式化百分比用模板字面量${}拼接多语言友好文案同时更新myregion、usage、fossilfuel多个 DOM 节点最后显示结果容器用try/catch兜底网络异常、API 返回错误或数据缺失时隐藏加载指示与结果区展示“抱歉无法获取该地区数据请检查 API 密钥与地区代码”的友好提示并通过console.error输出诊断日志。请求-响应的完整错误分支可概括为发起 API 调用 → 网络失败则报网络错误 → 响应状态非 OK 则报 API 错误 → 解析 JSON → 数据无效则报数据错误 → 全部通过才更新 UI → 无论成败最后都要隐藏加载指示。一句话总结本函数它演示了专业开发者日常必备的一组基本功——与外部服务器通信、鉴权、数据处理、界面更新与优雅的错误管理。从仓库源码看工程化细节对照 5-browser-extension/solution/package.json本扩展的工程配置包含包名carbon-trigger-extension依赖axios^1.15.0开发依赖webpack与webpack-cliengines要求 npm 9.0.0、node 18.0.0脚本npm run buildwebpack 打包、npm run watch监听模式、npm test占位。解决方案版 5-browser-extension/solution/src/index.js 相比课程文档的 fetch 示例还额外展示了三个细节数据完整性校验if (data?.carbonIntensity null || data?.fossilFuelPercentage null)使用可选链与空值检查在渲染前验证响应数据完整避免向用户展示未定义值图标联动calculateColor()依据碳强度值分段区间[0, 150, 600, 750, 800]对应绿/黄/红等色阶通过chrome.runtime.sendMessage({ action: updateIcon, ... })通知后台脚本更新扩展栏图标颜色——这正是课程中// TODO: calculateColor(carbonIntensity)注释指向的下一课内容存储键差异解决方案使用apiKeyregion课程教学代码使用apiKeyregionName两者均可工作注意保持一致即可。构建、安装与验证完成上述六个编号段的编码后按以下步骤构建并验证你的扩展npm install # 安装依赖 npm run build # webpack 打包生成 dist 目录安装到浏览器以 Edge 为例点击浏览器右上角“三点”菜单进入扩展管理页开启“开发人员模式”选择“加载解压缩的扩展”并指向打包输出的dist文件夹。首次使用需要准备一个 CO2 Signal API 密钥在其官网注册邮箱获取一个地区代码参照 Electricity Map 的区码例如波士顿可用US-NEISO。在扩展界面输入 API 密钥与地区代码并提交后扩展会保存设置并立即拉取数据刷新或重启浏览器后再次打开扩展应自动恢复并直接展示上次地区的最新碳数据点击清除按钮则可回到重新配置状态。进阶挑战与学习路线GitHub Copilot Agent 挑战使用 Agent 模式增强displayCarbonUsage目标包括1) 对失败的 API 调用实现带指数退避的重试机制2) 在发起请求前校验地区代码格式3) 带进度指示器的加载动画4) 在 LocalStorage 中缓存 API 响应并附 30 分钟过期时间戳5) 展示历史调用数据同时用 TypeScript 风格的 JSDoc 注释完整标注参数与返回类型。浏览器 API 探索挑战选一个浏览器内置 API 制作小演示体会 API 设计质量Geolocation API获取位置、Notification API桌面通知、HTML Drag and Drop API拖放交互、Web Storage API本地存储进阶、Fetch APIXMLHttpRequest 的现代替代。研究时可重点关注该 API 解决什么现实问题、如何处理错误与边界情况、使用时有哪些安全考量、跨浏览器支持情况如何。单元作业完成作业 5-browser-extension/2-forms-browsers-local-storage/assignment.md“采用一个 API”——从公开 API 清单中任选一个如随机狗狗图片、天气、名言、新闻头条、数字趣闻等设计并构建一个解决真实问题的浏览器扩展要求包含表单输入、带错误处理的 API 集成、LocalStorage 偏好存储、响应式界面、加载态与用户反馈并使用 ES6、async/await、try/catch编写规范注释的代码。评分维度覆盖 API 集成质量、代码质量、用户体验、LocalStorage 运用与文档完整性五个方面。能力成长时间轴按课程给出的节奏规划DOM 基础约 15 分钟→ LocalStorage 持久化约 20 分钟→ 表单处理约 25 分钟→ API 集成约 35 分钟→ 异步编程约 40 分钟→ 错误处理约 30 分钟→ 进阶模式缓存策略、速率限制、重试机制、性能优化约 1 周→ 生产技能安全实践、API 版本化、监控日志、可扩展架构约 1 个月。总结本课让你完成了一个从静态表单到动态数据应用的完整跃迁收获的能力清单包括精准的 DOM 元素定位与操作、基于 localStorage 的持久数据管理、实时数据拉取与鉴权、不阻塞界面的异步编程、优雅的异常处理、以及加载态/校验/平滑交互的用户体验设计。这些模式同样适用于单页应用、API 驱动的移动应用、Electron 桌面软件、企业级系统乃至 React/Vue/Angular 的数据管理——你已经掌握了现代 Web 开发中“数据获取 本地持久化 界面响应”这条核心主线的标准解法。下一步可以继续探索缓存策略、实时 WebSocket 连接与复杂状态管理等更进阶的主题。【免费下载链接】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),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →