微信 H5 缓存控制:后端重定向 & 前端强制刷新

在 Web 开发中,缓存是一把双刃剑。对于静态资源,它能极大提升加载速度;但对于业务逻辑频繁变动的 H5 页面(如支付、订单页),缓存往往会导致用户看到过期的数据或界面。最近在维护一个 uni-app 项目时,遇到了一段关于 H5 缓存控制的逻辑,引发了我对于“后端重定向加时间戳”和“前端 JS 加时间戳”这两种方案的思考。虽然两者的最终目的一致,但在 Hash 模式下,它们的实现原理和效果有着本质的区别。

一、 问题背景

在应用启动的生命周期中,通常会有这样一段逻辑:当用户访问特定的关键页面(如支付、订单页)时,如果当前 URL 中缺少时间戳参数,前端会自动解析 URL,追加当前时间戳,并强制页面刷新。

这就引出了一个问题:为什么不直接在后端重定向时加时间戳?这两种方式有什么区别?

二、 核心区别:执行时机与作用域

虽然两种方式都能通过修改 URL 参数来欺骗浏览器,使其认为这是一个新请求,进而绕过缓存,但它们的工作流程完全不同。

我们可以用一个通俗的“进商场”例子来类比:

维度后端重定向加时间戳 (迎宾员模式)前端 JS 加时间戳 (服务员模式)
执行者服务器浏览器
发生时机用户发起请求的瞬间,页面还未加载页面已经加载,JS 开始运行后
工作流程浏览器请求 -> 服务器拦截并返回 302 -> 浏览器自动跳转新 URL浏览器加载旧页面 -> JS 检测 URL -> JS 修改 href -> 浏览器跳转
用户体验无感知,直接进入最终页面可能会看到旧页面闪一下,然后跳转刷新
主要作用解决入口缓存问题解决内部路由缓存问题

三、 为什么这里必须用前端方案?(Hash 模式的特殊性)

这段代码所在的 uni-app 项目是一个典型的 SPA(单页应用),且采用了 Hash 模式(URL 中包含 #)。这是选择前端方案的决定性因素。

1. 后端的“盲区”

在 Hash 模式下,URL 形如 http://example.com/#/order
当用户在应用内部跳转(如从首页跳转到订单页)时,仅仅是 # 后面的 Hash 值发生了变化。这个过程不会向服务器发送 HTTP 请求,后端完全感知不到用户进入了哪个页面。因此,后端无法在用户进入特定页面时进行拦截并重定向。

2. 关键细节:时间戳加在哪里?

在 Hash 模式下实现前端刷新,有一个极易被忽视的细节:时间戳参数必须加在 # 号之前

  • ❌ 错误做法:加在 # 后面(如 #/order?t=123)。
    这仅改变了前端路由状态,不会触发浏览器刷新,也就无法更新 HTML 或 JS 的缓存。
  • ✅ 正确做法:加在 # 前面(如 /?t=123#/order)。
    这改变了请求的 Base URL,迫使浏览器向服务器发起一次全新的请求,从而拉取最新的页面资源。

3. 兜底机制

当用户已经在应用内部跳转到了订单页,此时如果浏览器缓存了旧的 HTML 结构,用户可能看到错误的数据。这时候,只有运行在浏览器里的 前端 JS 能够感知到“我现在在订单页”并且“URL 里没有时间戳”,从而执行强制刷新逻辑。

四、 总结与建议

后端重定向前端强制刷新并不是二选一的关系,而是互补的关系:

  • 后端重定向:适用于解决首次访问外部链接跳转时的缓存问题。它是第一道防线,确保用户进门时拿到的就是最新的菜单。
  • 前端强制刷新:适用于解决应用内部跳转时的缓存问题。它是最后一道防线,确保用户在应用内部流转时,关键业务页面(如支付)的数据绝对是最新的。

最佳实践建议
虽然前端加时间戳能解决问题,但会带来“页面闪烁”的副作用。更优的方案是:

  1. 后端配置正确的 HTTP 缓存策略(如 Cache-Control: no-cache),从源头告诉浏览器不要缓存 HTML。
  2. 对于无法控制服务头的场景,或者为了兼容性,使用文中的前端 JS 方案作为保底手段,专门针对对数据一致性要求极高的页面(如支付、订单)进行处理,且务必将时间戳加在 Hash 之前

Read more

# Flink 生产环境调优案例

# Flink 生产环境调优案例

Flink 生产环境调优案例:从 5000TPS 到 50000TPS 的实战之路 一、生产环境背景 1.1 业务场景 实时数据 pipeline(2023 年双 11 大促): 数据源:Kafka(用户行为日志) ├── Topic:user_behavior_log ├── 分区数:100 ├── 峰值 TPS:50,000+ └── 数据量:日增 500GB 处理逻辑: ├── 数据清洗(过滤、格式化) ├── 实时聚合(UV/PV/GMV) ├── 实时 Join(用户信息 + 行为) └── 结果输出(Kafka + StarRocks) SLA

(论文速读)UWDET:基于物联网的资源有限水下目标探测训练增强

(论文速读)UWDET:基于物联网的资源有限水下目标探测训练增强

论文题目:UWDET: IoT-Enabled Training Enhancement for Resource-Limited Underwater Object Detection(UWDET:基于物联网的资源有限水下目标探测训练增强) 期刊:IOTJ 摘要:在支持物联网(IoT)的海洋传感器网络中,由于资源限制,水下物体检测(UWDET)面临挑战,例如小目标识别和规模变化。这些挑战导致样本不平衡和标签分配的模糊性。虽然像你只看一次(YOLO)系列这样的框架是有效的,但由于这些问题,它们的水下性能往往不足。本文介绍了为物联网环境中的UWDET量身定制的训练增强策略,旨在减少推理资源消耗,同时保持高检测准确性。重要的是,我们的方法保留了现有的网络架构,并且不会延长推理时间。该方法包括三个主要元素:高斯重叠损失(GOL),它通过二维高斯分布解释边界盒(BBoxes),从而增强定位并解决资源有限环境下小物体的尺度不平衡问题。动态任务联合分配(DTJA)基于分类置信度和回归质量修改正样本分配,从而最大限度地减少训练过程中的假阳性率。规范焦点损失(NFL)采用归一化的联合分配度量作为连

ESP32 (ESPectre)+Grafana构建专业级CSI监控面板

ESP32 (ESPectre)+Grafana构建专业级CSI监控面板

适合:养老院、看护中心、项目交付、客户演示效果:专业级 CSI 波形图 + 运动强度曲线 + 多房间监控墙 一、整体数据流 1. 硬件环境 ESP32S3 Dev Module开发板(主要是国内兼容版本的ESP32S3-N16R8开发板) 2. 软件环境 * ESPectre(ESP32) * Home Assistant * InfluxDB 数据库(存历史数据) * Grafana(可视化面板) 建议通过Linux 服务器运维管理面板1Panel进行安装相关服务组件 。 3. 整体数据流 ESP32 ESPectre → ESPHome → Home Assistant → InfluxDB 2.8 → Grafana 专业面板 ESP32 (ESPectre) ↓(ESPHome 本地直连) Home Assistant(已实现)

MySQL 常用数据类型的系统总结

一、数值型(存储数字,含整数、小数、布尔值) 1. 整数类型(INT 系列) 数据类型 字节数 取值范围(有符号) 取值范围(无符号) 核心特性 适用场景 TINYINT 1 -128 ~ 127 0 ~ 255 占用空间最小 状态标记(0/1)、年龄(简化)、评分等级 SMALLINT 2 -32768 ~ 32767 0 ~ 65535 中小型整数 班级人数、序号、金额(分) MEDIUMINT 3 -8388608 ~ 8388607 0 ~ 16777215 中大型整数 数据量较大的