导读:本期聚焦于小伙伴创作的《JavaScript怎样操作数据库?IndexedDB具体如何使用?》,敬请观看详情。浏览器里直接存大量结构化数据该选什么方案?相比localStorage只能存字符串且容量有限,IndexedDB提供事务型、异步、可建索引的NoSQL能力。它通过对象仓库存储记录,支持键值与游标查询,适合离线应用与缓存场景。使用时先开数据库连接,在onupgradeneeded里建仓库和索引,再用事务读写。注意所有操作皆异步,需处理好版本变更与错误回调,否则易出现连接阻塞或数据丢失。

在纯前端环境中,JavaScript并不像服务端语言那样直接连MySQL或PostgreSQL,而是借助浏览器提供的存储接口。其中IndexedDB是一套底层API,允许网页在用户本地保存大量结构化数据,并支持索引、事务和异步查询,弥补了localStorage只能存字符串、容量小的不足。

JavaScript怎样操作数据库?IndexedDB具体如何使用?

一、IndexedDB的核心概念

IndexedDB是一个基于事务的NoSQL数据库,运行在浏览器中。它以“数据库—对象仓库(object store)—记录”的层级组织数据,每条记录都有一个主键,可以是系统自动生成,也可以由开发者指定。与关系型数据库不同,这里不需要建表语句,仓库内的数据结构可以灵活变化。

另一个关键是“事务”。所有读写操作都必须包裹在事务里,事务分为只读、读写和版本变更三种模式。如果某个事务正在修改仓库,其他读写事务会被阻塞,这保证了数据一致性。异步设计则意味着调用后通过事件或Promise拿到结果,不会卡住页面渲染。

1.1 数据库与版本

每个IndexedDB数据库都有名称和版本号。当版本号升高时,会触发onupgradeneeded回调,此时才能创建或删除对象仓库、建立索引。如果版本处理不当,旧页面持有低版本连接就会导致升级阻塞,因此关闭多余连接很重要。

打开数据库的代码非常简单,但回调逻辑必须写全。下面演示最基本的打开过程,注意错误处理和版本变更分开写,避免升级失败无声无息。

// 打开名为 appDB 的数据库,版本为 1
const request = indexedDB.open('appDB', 1);

request.onupgradeneeded = function(event) {
  const db = event.target.result;
  // 如果不存在用户仓库则创建,主键为 id
  if (!db.objectStoreNames.contains('users')) {
    const store = db.createObjectStore('users', { keyPath: 'id' });
    // 建立按姓名查询的索引
    store.createIndex('by_name', 'name', { unique: false });
  }
};

request.onsuccess = function(event) {
  const db = event.target.result;
  console.log('数据库打开成功');
};

request.onerror = function(event) {
  console.error('打开失败', event.target.error);
};

二、写入与读取数据

写入数据要走读写事务。通过db.transaction(storeName, 'readwrite')拿到事务对象,再用objectStore方法定位仓库,调用addput。add在主键冲突时报错,put则会覆盖。因为操作异步,通常包装成Promise更方便。

读取分为按主键直接取和通过索引游标遍历。直接取用get(key),索引查询用index('by_name').get('张三')。若需批量处理,游标能一条条吐出记录,适合分页或统计。下面示例展示Promise化写入与按主键读取。

function addUser(db, user) {
  return new Promise((resolve, reject) => {
    const tx = db.transaction('users', 'readwrite');
    const store = tx.objectStore('users');
    const req = store.put(user);
    req.onsuccess = () => resolve();
    req.onerror = () => reject(req.error);
  });
}

function getUser(db, id) {
  return new Promise((resolve, reject) => {
    const tx = db.transaction('users', 'readonly');
    const store = tx.objectStore('users');
    const req = store.get(id);
    req.onsuccess = () => resolve(req.result);
    req.onerror = () => reject(req.error);
  });
}

// 使用示例
request.onsuccess = async function(event) {
  const db = event.target.result;
  await addUser(db, { id: 1, name: '张三', age: 28 });
  const u = await getUser(db, 1);
  console.log(u);
};

2.1 使用游标遍历

当数据量较大,不宜一次全取。游标通过openCursor逐步前进,能在前端做过滤。以下代码打印所有年龄大于20的用户,体现了IndexedDB对非主键字段的灵活处理。

游标回调里要手动调用cursor.continue()才会取下一行,否则停止。这种拉取方式对内存友好,也方便在遍历时做增量渲染。

function eachAdult(db) {
  const tx = db.transaction('users', 'readonly');
  const store = tx.objectStore('users');
  const req = store.openCursor();
  req.onsuccess = function(event) {
    const cursor = event.target.result;
    if (cursor) {
      const user = cursor.value;
      if (user.age > 20) {
        console.log(user.name);
      }
      cursor.continue();
    }
  };
}

三、常见误区与注意事项

不少人把IndexedDB当同步存储用,在事务外直接读变量,结果拿到undefined。必须明确:所有数据操作都在事务生命周期内有效,事务结束后对象仓库引用失效。另外,隐私模式或部分浏览器会限制容量,写入前最好捕获异常。

还有一个坑是版本升级时旧连接未关闭。若用户打开了两个标签页,一个升级数据库,另一个还占着旧版本,升级事务会一直挂起。解决办法是在onversionchange里主动调用db.close(),提示用户刷新。

IndexedDB虽强,但不是替代服务端的方案。它用于离线缓存、本地草稿、日志队列等,敏感数据仍需加密且不可信赖客户端。

3.1 简单对比localStorage

下表列出两者差异,帮助选型。若只是存 token 或配置,localStorage更简单;若存聊天记录、表单离线队列,IndexedDB才合适。

特性localStorageIndexedDB
数据类型仅字符串结构化对象
容量约5MB数百MB起
查询全量读后筛索引与游标
异步同步阻塞异步非阻塞

四、封装建议

原生API事件回调偏底层,实际项目常用Promise或第三方轻量库包装。自己封装时,建议统一错误类型、提供单例数据库连接、在页面卸载前关闭连接。这样业务代码只调用db.get()之类方法,不碰事务细节。

总之,JavaScript操作数据库在前端语境下主要指IndexedDB。掌握打开、升级、事务、索引与游标,就能在浏览器里构建稳定的本地数据层,为离线应用打下基础。

JavaScriptIndexedDB前端数据库修改时间:2026-08-06 23:03:32

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。