浏览器的背包:数据获取与存储完全指南
浏览器的隐藏超能力:Web API开发者指南(4部分系列)
浏览器的背包:数据获取与存储 ← 当前文章
欢迎回到我们探索浏览器隐藏超能力的旅程!到目前为止,我们已经学习了为什么Web API是必不可少的(第1部分)以及如何使用DOM API操作页面(第2部分)。我们的应用程序现在是交互式的,但它们有一个问题:它们没有记忆,也无法与外部世界交流。
今天,我们要给我们的浏览器一个背包。这个背包有两个口袋:
一个对讲机,可以与互联网上任何地方的服务器通信。这就是Fetch API。
一个笔记本,可以记录信息并在以后记住它。这就是Web Storage API。
掌握这两个API将使你的原生JavaScript项目从简单的玩具提升为完整的应用程序。
你的对讲机:Fetch API
多年来,开发者使用一个笨重的工具XMLHttpRequest(通常昵称为"XHR")来发起网络请求。它很强大,但语法复杂且不直观。
Fetch API是它的现代、强大且更清洁的替代品。它基于Promise,这使得处理异步操作(比如等待服务器响应)变得轻而易举。
发起GET请求(获取数据)
让我们从免费的JSONPlaceholder API获取一些用户数据,就像我们在第1部分中预览的那样。
async/await语法是处理Promise最清洁的方式。让我们分解这个过程:
- // 一个获取并显示用户的函数
- async function fetchUsers() {
- const userList = document.querySelector('#user-list');
- try {
- // 1. "await"服务器的响应
- const response = await fetch('https://jsonplaceholder.typicode.com/users');
- // 2. 检查响应是否成功(状态码200-299)
- if (!response.ok) {
- // 如果不成功,抛出错误被catch块捕获
- throw new Error(`网络响应不正常: ${response.statusText}`);
- }
- // 3. 响应体是一个流。我们需要将其解析为JSON。
- // 这也是一个异步操作,所以我们需要"await"它。
- const users = await response.json();
- // 4. 现在我们有了数据!我们可以使用第2部分的DOM技能。
- users.forEach(user => {
- const li = document.createElement('li');
- li.textContent = user.name;
- userList.append(li);
- });
- } catch (error) {
- // 如果try块中任何地方出错,都会被这里捕获。
- console.error('获取错误:', error);
- userList.textContent = '加载用户失败。';
- }
- }
- // 调用函数
- fetchUsers();
就是这样!在几行可读的代码中,我们发起了一个网络请求,处理了潜在的错误,解析了数据,并更新了DOM。不需要任何库。
发起POST请求(发送数据)
那么向服务器发送数据呢?Fetch也能优雅地处理这个。我们只需要传递第二个参数:一个选项对象。
- async function createUser(userData) {
- try {
- const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
- method: 'POST', // 指定HTTP方法
- headers: {
- // 告诉服务器我们正在发送JSON
- 'Content-Type': 'application/json'
- },
- // 我们发送的数据,转换为JSON字符串
- body: JSON.stringify(userData)
- });
- if (!response.ok) {
- throw new Error(`HTTP错误!状态: ${response.status}`);
- }
- const result = await response.json();
- console.log('成功创建用户:', result);
- } catch (error) {
- console.error('创建用户时出错:', error);
- }
- }
- // 使用示例:
- const newUser = {
- name: 'Jane Doe',
- username: 'janedoe99',
- email: 'jane@example.com'
- };
- createUser(newUser);
你的笔记本:Web Storage API
好的,我们可以获取数据。但如果用户刷新页面怎么办?我们漂亮的用户列表就消失了。我们需要一种在浏览器本身存储信息的方法。
Web Storage API提供了一个简单的、持久的键值存储。它有两种形式。
1. localStorage
将localStorage想象成一个永久的笔记本。保存在这里的数据即使在浏览器关闭并重新打开后也会持续存在。它非常适合保存用户设置(比如"暗色模式"偏好)或用于身份验证的JWT令牌。
API非常简单:
localStorage.setItem('key', 'value'): 保存一个值。
localStorage.getItem('key'): 检索一个值。
localStorage.removeItem('key'): 删除一个值。
localStorage.clear(): 删除所有内容。
重要提示: localStorage只能存储字符串。如果你想存储JavaScript对象,必须先用JSON.stringify()将其转换为字符串,检索时用JSON.parse()解析回来。
示例:保存主题偏好。
- const themeToggleButton = document.querySelector('#theme-toggle');
- // 页面加载时,检查localStorage中是否保存了主题
- const savedTheme = localStorage.getItem('theme');
- if (savedTheme) {
- document.body.classList.add(savedTheme);
- }
- themeToggleButton.addEventListener('click', () => {
- document.body.classList.toggle('dark-mode');
- // 切换后,保存当前状态
- if (document.body.classList.contains('dark-mode')) {
- localStorage.setItem('theme', 'dark-mode');
- } else {
- localStorage.removeItem('theme'); // 或者设置为'light-mode'
- }
- });
2. sessionStorage
sessionStorage就像当前浏览器标签页的便利贴。它与localStorage有完全相同的API(setItem、getItem等),但有一个关键区别:当标签页关闭时,数据会被清除。
它非常适合存储不应该永久存在的临时信息,比如多页面表单的数据或结账前购物车的状态。
未来一瞥:IndexedDB
对于简单的键值对,localStorage是完美的。但如果你需要存储大量结构化数据并高效查询,就像真正的数据库一样呢?为此,浏览器提供了IndexedDB。它是一个完整的、事务性的客户端数据库。它比localStorage复杂得多,但它是构建强大的离线优先应用程序的正确工具。我们不会在这里详细讨论它,但它是你数据存储旅程中的下一个逻辑步骤。
下一步是什么?
我们的应用程序正在变得智能。它可以控制页面(DOM),与服务器通信(Fetch),并记住事情(Web Storage)。它开始感觉像一个真正的应用程序了。
但我们可以进一步推动它。我们可以让它与用户的物理世界互动。
在第4部分中,我们将通过探索设备API来弥合数字与物理的鸿沟。我们将获取用户的位置,弹出系统通知,并与他们的剪贴板互动!
总结
通过掌握Fetch API和Web Storage API,你的浏览器应用程序现在具备了:
网络通信能力:可以与远程服务器进行数据交换
数据持久化:可以在浏览器中保存和检索信息
错误处理:能够优雅地处理网络错误和异常情况
用户体验优化:通过本地存储提供更好的用户体验
这些API是现代Web开发的基础,掌握它们将大大提升你的前端开发能力。
