页面重载时sql.js读取SQLite数据滞后及修改缓存配置后报错求助
问题排查与解决方案
一、数据滞后原因
- 核心问题是静态数据库文件
/sensors.db被缓存了:浏览器或服务端默认会给静态资源设置缓存策略,即使你用Ctrl+F5强制刷新,部分场景下依然会命中已缓存的旧版数据库文件,导致拿到的数据不是最新的。 - 和
Promise.all、.then逻辑没有关系,你的异步执行逻辑本身是正确的。
二、修改后报错原因
你修改后的代码有三处错误:
- fetch参数格式错误:
cache-control属于请求头字段,必须放在headers配置项下,直接写在fetch的根配置中不会生效。 - 路径错误:你原本请求的是
/sensors.db,修改后改成了/db.db,如果服务端没有对应路径的数据库文件,返回的404页面内容转成二进制后不是合法的sqlite文件,就会触发file is not a database错误。 - SQL语句错误:你修改后执行的SQL是
select x from db;,这里的db是你代码里的数据库实例变量名,不是表名,你之前的表名是sensors,SQL语句操作的对象应该是表名。
三、正确修复代码
方案1:添加缓存控制头
// 保留你原有sql.js初始化配置 const config_sqljs = { locateFile: filename => ( 'https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.5.0/sql-wasm.wasm' ) } const sqlPromise = initSqlJs(config_sqljs) const dataPromise = fetch('/sensors.db', { method: "GET", headers: { "Cache-Control": "no-store, no-cache, must-revalidate", "Pragma": "no-cache" }, cache: "no-store" }) .then(res => { if (!res.ok) throw new Error(`数据库请求失败,状态码:${res.status}`) return res.arrayBuffer() }) Promise.all([sqlPromise, dataPromise]) .then(([SQL, buf]) => { const db = new SQL.Database(new Uint8Array(buf)) // 保留你之前的正确SQL语句,不要改表名 const res = db.exec('select time_,temp,humi from sensors where topic ="/y/sensors" and (date="29.11.2021" or date="30.11.2021" or date="01.12.2021");') const values = res[0].values; let labelx = values.map((arr) => arr[0]); let y = values.map((arr) => arr[1]); let y2 = values.map((arr) => arr[2]); // 后续你的chart.js渲染逻辑写在这里 }) .catch(err => console.error('执行错误:', err))
方案2:添加时间戳后缀(彻底规避缓存)
如果服务端配置了静态资源强缓存,直接加请求头也不生效的话,可以给数据库请求路径加动态时间戳,每次请求的URL都是唯一的,完全不会命中缓存:
// 只需要修改fetch的URL即可,其他配置和方案1一致 const dataPromise = fetch(`/sensors.db?t=${Date.now()}`) .then(res => { if (!res.ok) throw new Error(`数据库请求失败,状态码:${res.status}`) return res.arrayBuffer() })
内容的提问来源于stack exchange,提问作者dabozz
相关产品推荐
相关产品推荐

