代码 Inertia.js 3.9:后台标签页轮询可暂停,退出登录后 Back 键不再翻出缓存里的受保护页面

2026-10-15 21:03:21

Inertia.js 3.9:后台标签页轮询可暂停,退出登录后 Back 键不再翻出缓存里的受保护页面

Inertia.js v3.9.0 / v3.9.1 于 2026-10-13 发布,两个改动都落在平时容易被忽略的边界上:标签页不可见时轮询该怎么跑,以及清理历史记录时 prefetch 缓存要不要一起清。

  • 仓库:https://github.com/inertiajs/inertia
  • Releases:https://github.com/inertiajs/inertia/releases
  • 参考:laravel-news.com/inertia-3-9-0、azeemhassni.com

轮询的后台行为:background 取代 keepAlive

usePoll() 与 router.poll() 新增 background 选项,三个取值:

  • throttle:默认值,保留旧行为——标签在后台时,每第 10 个间隔发一次请求。
  • pause:标签隐藏时完全停止轮询。
  • continue:无论标签可见与否,都按完整间隔轮询。它替代了已弃用的 keepAlive。

默认值选 throttle 是为了不改变现有应用的行为,已经在用轮询的页面升级后节奏不变;要从旧的 keepAlive 迁过来,把该处改成 continue 即可。

pause 的补发时机是最容易理解错的地方。它不是「每次切回标签就补发一次」:只有在隐藏期间某次轮询已经到期,标签重新可见时才立即补发一次;如果还没到期,就等当前间隔走完。所以来回快速切标签不会每次都产生请求,只有真正错过的那些才会补上。对仪表盘、通知这类后台无意义、前台才需要新鲜的轮询来说,这个语义比简单地「恢复就发」更省请求。

顺带修了一个旧问题:如果轮询是在标签已经隐藏之后才启动的,此前它会一直按完整间隔跑下去,直到下一次可见性变化才被纠正。现在这种情况同样会遵循 background 的设置。

另外,usePoll 现在会暴露 polling 状态,组件里可以直接读取。

clearHistory 一并清空 prefetch 缓存

router.clearHistory() 和服务端的 Inertia::clearHistory() 现在会同时清空 prefetch 缓存。两个配套行为一起生效:已经在飞行中的 prefetch 请求,完成后不再写回缓存;router.flushAll() 也受同样的保护。

这修的是一个具体现象:退出登录后按 Back,可能拿到缓存的受保护页面,直到那条缓存条目自然过期。加上飞行中请求不回写之后,清理动作不会因为一个还没返回的 prefetch 而失效。

需要说清边界:这是本地展示与隐私层面的修复,不是服务端鉴权被绕过。问题出在已经落到本地缓存里的页面被重新翻出来展示,而不是服务端放行了本来不该通过的请求——服务端该拒绝的仍然拒绝。

navigate 事件新增 type 字段,取值 initial / visit / history。有了它,可以在历史回退恢复页面之后判断这是不是一次 history 导航,再用 router.reload({ only: [...] }) 只刷新已经过期的 props,而不必整页重载。

同一批修复里还处理了两个竞态:InfiniteScroll 在导航之后仍然合并旧结果;以及正在进行的页面更新覆盖刚刚由历史恢复出来的页面。

复制全文 生成海报 Inertia.js Vue 前端 Laravel

推荐文章

程序员茄子在线接单