资讯详情

资讯详情

Web-Dev-For-Beginners 浏览器扩展教程 Part 2:用 LocalStorage 与异步 API 调用让扩展“活”起来

Web-Dev-For-Beginners 浏览器扩展教程 Part 2用 LocalStorage 与异步 API 调用让扩展“活”起来【免费下载链接】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 课程中浏览器扩展项目Carbon Trigger 扩展的第二课完整讲解如何在扩展的src/index.js中用document.querySelector建立 DOM 引用、通过localStorage实现跨会话记忆、拦截表单提交并用async/await axios 调用 CO2 Signal REST API 获取区域电网碳排放数据。读完后你能独立完成一个“带记忆、能联网、有加载态和错误提示”的浏览器扩展核心逻辑。课程定位从静态表单到动态扩展本仓库的 浏览器扩展项目 分为多个阶段。第一课1-about-browsers完成了 HTML 表单、结果div以及基于 webpack 的构建环境搭建本课2-forms-browsers-local-storage的任务是把静态界面变成活的扩展提交表单时调用 CO2 Signal APIhttps://api.co2signal.com/v1/latest查询用户所在电网区域的碳排放强度把 API key 与区域代码存入浏览器 LocalStorage下次打开扩展时自动加载上次配置提供 loading 状态、错误提示与重置clear按钮管理完整的 UI 状态机。课程提示按“合适文件中的编号分段numbered segments”放置代码。从仓库中的 起始代码文件 可以看到这套编号体系//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注释中的//1~//6就是官方给出的代码落位标记先建 DOM 引用1再加监听器与启动逻辑2依次是init3、handleSubmit4、setUpUser5、API 调用6。第一步建立 DOM 元素引用JavaScript 操作界面之前必须先拿到 HTML 元素引用。扩展按 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);要点全部字段都通过上一课 HTML 中定义的 CSS 类名引用而不是行内id选择器与样式层保持一致每个元素引用存入const变量后续init、reset、displayCarbonUsage等函数直接复用避免重复查询 DOM。第二步添加事件监听器并启动初始化在文件底部为表单和重置按钮注册监听器并立即调用init()建立扩展的初始状态form.addEventListener(submit, (e) handleSubmit(e)); clearBtn.addEventListener(click, (e) reset(e)); init();form的submit事件在用户按回车或点击提交时触发事件对象(e)被传给handleSubmitclearBtn的click事件触发reset用于清除已保存的区域配置这里使用了箭头函数简写课程引导思考它等价于(e) { handleSubmit(e); }的传统 function 表达式两种写法都可以。init()立即执行一次决定首屏展示表单还是直接加载上次保存的数据。课程还给出一个自测问题如果在表单提交中忘记e.preventDefault()页面会重新加载所有 JavaScript 状态丢失用户体验被中断。第三步init() 与 reset() —— 基于 LocalStorage 的状态分派init()是整个扩展的“导航系统”检查用户是否使用过本扩展并据此调整界面function init() { //if anything is in localStorage, pick it up const storedApiKey localStorage.getItem(apiKey); const storedRegion localStorage.getItem(regionName); //set icon to be generic green //todo if (storedApiKey null || storedRegion null) { //if we dont have the keys, show the form form.style.display block; results.style.display none; loading.style.display none; clearBtn.style.display none; errors.textContent ; } else { //if we have saved keys/regions in localStorage, show results when they load displayCarbonUsage(storedApiKey, storedRegion); results.style.display none; form.style.display none; clearBtn.style.display block; } }; function reset(e) { e.preventDefault(); //clear local storage for region only localStorage.removeItem(regionName); init(); }逐段解读用两个const从 LocalStorage 取出apiKey与regionName判断用户是否已保存过配置新用户分支任一值为null把form显示为block同时隐藏结果区、loading 指示与重置按钮并把错误文本清空老用户分支直接用存储的凭证调用displayCarbonUsage()发起 API 请求隐藏表单、显示重置按钮reset()只removeItem(regionName)保留 API key降低用户操作成本然后重新init()回到首屏表单。注意//set icon to be generic green处的todo注释——动态图标功能是第三课的内容本课刻意留白。LocalStorage扩展的“持久记忆”LocalStorage 是浏览器把字符串以key-value对形式持久化保存的机制通过 Web Storage API 的三个方法控制localStorage.getItem(key)取值键不存在时返回nullinit()正是靠这个null判断新老用户localStorage.setItem(key, value)写入setUpUser()使用localStorage.removeItem(key)删除reset()使用。它与 SessionStorage 的关键区别LocalStorage不会过期浏览器关闭、计算机重启后数据仍在而 SessionStorage 在浏览器关闭后即刻被清除。三个重要的适用前提与安全边界作用域隔离浏览器扩展拥有自己独立的 LocalStorage与主浏览器窗口的各个页面相互隔离。也就是说扩展里存的apiKey不会出现在普通网页的存储里反过来也一样。调试方式在 Edge/Chrome 中右键扩展面板选择“检查Inspect”打开 DevTools 的Application面板 →Local Storage可以看到本扩展存储的键值本课截图即此视图。安全警示课程明确提醒——“把 API 密钥放进 LocalStorage 一般不是好主意”因为同源的 JavaScript 都能读到它。本课采用这种方案是因为该扩展纯粹用于学习、不会发布到应用商店生产环境应把敏感凭证放到服务端安全存储中。第四步拦截表单提交handleSubmit接收事件对象阻止浏览器默认的“提交即刷新”行为并把两个输入框的值传给setUpUserfunction handleSubmit(e) { e.preventDefault(); setUpUser(apiKey.value, region.value); }课程在此提示回忆第一课的 HTMLapiKey与region两个输入字段都带有required属性浏览器会在handleSubmit执行前强制用户填齐两个字段天然完成了一层输入校验。第五步setUpUser() 保存配置并发起首次请求setUpUser负责“持久化 切换 UI 发请求”三件事的协调function setUpUser(apiKey, regionName) { localStorage.setItem(apiKey, apiKey); localStorage.setItem(regionName, regionName); loading.style.display block; errors.textContent ; clearBtn.style.display block; //make initial call displayCarbonUsage(apiKey, regionName); }执行顺序先把 API key 与区域名写入 LocalStorage保证下次init()能识别为老用户→ 显示 loading 指示 → 清空残留错误信息 → 显示重置按钮 → 立即发起首次 API 调用。核心displayCarbonUsage() 异步调用 CO2 Signal APIAPI 与 REST 背景APIApplication Programming Interfaces为程序之间提供标准化的互操作方式。本课使用的 CO2 Signal API 是一个典型的REST API——RESTRepresentational State Transfer指通过精心构造的 URL方法 端点 查询参数来读取/操作资源响应通常是 JSON。例如这里方法与端点GET https://api.co2signal.com/v1/latest查询参数countryCode区域代码如波士顿对应US-NEISO认证auth-token请求头携带 API key为什么必须用 asyncasync关键字让函数异步执行await会在数据返回前挂起而不阻塞整个扩展线程。API 的响应速度不受本地代码控制甚至可能完全无响应因此这类“不确定能否成功、何时成功”的调用必须异步处理并用try/catch兜底。完整实现import axios from ../node_modules/axios; async function displayCarbonUsage(apiKey, region) { try { await axios .get(https://api.co2signal.com/v1/latest, { params: { countryCode: region, }, headers: { auth-token: apiKey, }, }) .then((response) { let CO2 Math.floor(response.data.data.carbonIntensity); //calculateColor(CO2); loading.style.display none; form.style.display none; myregion.textContent region; usage.textContent Math.round(response.data.data.carbonIntensity) grams (grams C02 emitted per kilowatt hour); fossilfuel.textContent response.data.data.fossilFuelPercentage.toFixed(2) % (percentage of fossil fuels used to generate electricity); results.style.display block; }); } catch (error) { console.log(error); loading.style.display none; results.style.display none; errors.textContent Sorry, we have no data for the region you have requested.; } }逐行拆解这个“大函数”asynctry/catchaxios 返回 PromiseAPI 随时可能失败网络问题、key 无效、区域不支持失败时走catch把 loading 与结果区隐藏并在.errors区显示友好提示而不是让扩展崩溃params: { countryCode: region }axios 会把它序列化为 URL 查询串?countryCodeXXXheaders: { auth-token: apiKey }CO2 Signal 采用 header 认证方式密钥通过auth-token头传递不放进 URL避免出现在访问日志中响应解析成功时从response.data.data取出两个核心字段——carbonIntensity每千瓦时的 CO2 克数取整后展示和fossilFuelPercentage发电用化石燃料百分比toFixed(2)保留两位小数写入myregion、usage、fossilfuel三个元素UI 状态切换请求成功后隐藏 loading 与表单、显示.result-container完成从“加载态”到“结果态”的过渡被注释的calculateColor(CO2)预留给下一课——按 CO2 数值给浏览器工具栏图标染色。构建、运行与验证扩展的构建配置见 package.json依赖axios ^1.15.0构建工具为 webpacknpm run build即执行webpack另提供npm run watch监听模式要求 Node 18、npm 9。npm install npm run build构建后在 Edge 中右上角“···”菜单 → 扩展 → “Load Unpacked”加载dist文件夹详见 安装说明。在扩展面板填入 CO2 Signal API key 与区域代码后提交即可看到 loading → 结果的完整流程刷新扩展面板后由于 LocalStorage 已保存配置会跳过表单直接自动拉取数据——这正是init()老用户分支的效果。源码佐证仓库最终版实现的差异仓库 solution/src/index.js 是完成全部三课后的最终版与本课代码相比有几处值得注意的演进可作为“课程代码 → 生产代码”的对照函数形态init、reset、handleSubmit、setUpUser全部改为箭头函数const ... async (...) {...}见 index.js#L83-L123且都标记为async存储键名最终版使用键region而非本课的regionNameindex.js#L72-L92迁移时注意 localStorage 键的兼容性防御性取值displayCarbonUsage中增加const data response?.data?.data;可选链取值并校验carbonIntensity/fossilFuelPercentage是否为空缺失时主动throwindex.js#L42-L47比课程版对异常响应更稳健图标联动已就位init()里原本的//todo被chrome.runtime.sendMessage({ action: updateIcon, value: { color: green } })替换index.js#L94-L100calculateColor()按[0, 150, 600, 750, 800]五档 CO2 值映射到五种颜色index.js#L17-L32——这正是本课被注释掉的calculateColor(CO2)在第三课的落地。延伸挑战与课后作业课程鼓励选一个 Web/Browser API 深入调研如 HTML Drag and Drop API并回答好的 API 应当具备什么特征如何定义、如何处理边界情况、跨浏览器支持度如何。配套作业 Adopt an API 要求自选一个免费公开 API构建完整的浏览器扩展验收标准包括表单收集 API 所需参数LocalStorage 保存用户偏好/密钥async/awaittry/catch的异步调用与错误处理loading 状态与用户反馈浏览器重启后配置仍然有效README 说明所选 API、安装方式、所需密钥并附运行截图。评分维度Rubric覆盖 API 集成、代码质量、用户体验、LocalStorage 使用与文档五项其中“LocalStorage”一档明确要求“带有数据校验与管理的存储使用”与本课的init()分派逻辑一脉相承。小结本课程的完整调用链是init()读取 LocalStorage 分派新老用户 → 表单submit触发handleSubmit→setUpUser持久化配置并切换 loading 态 →displayCarbonUsage以auth-token头认证、countryCode参数查询 CO2 Signal REST API → 成功后渲染carbonIntensity与fossilFuelPercentage失败则在.errors区降级提示。掌握这条“DOM 引用 事件监听 LocalStorage 持久化 异步 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),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →