后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载本篇技术指南围绕 Yii 2 框架的客户端缓存能力展开通过配置yii\filters\HttpCache动作过滤器为控制器操作渲染的页面设置Last-Modified、ETag、Cache-Control三类 HTTP 缓存头从而让浏览器等客户端直接复用已缓存内容节省服务端渲染与页面传输的开销。读完本文你将掌握 HttpCache 的完整配置方法、底层缓存校验流程含 304 响应原理以及 Session 与缓存头冲突的解决方案可直接在真实项目中落地客户端缓存策略。从服务器端缓存到客户端缓存在前面的章节参见 缓存概览中介绍的数据缓存、片段缓存、页面缓存都属于服务器端缓存缓存内容存放在服务端文件、内存、数据库等下次请求时由服务端直接读取缓存结果省去的是重复计算与查询。而HTTP 缓存客户端缓存走的是另一条路把「页面是否变化」的判定权交给客户端。服务器通过 HTTP 响应头告诉浏览器页面最后修改时间或内容指纹浏览器在后续请求中携带条件请求头If-Modified-Since/If-None-Match若内容未变化服务器直接返回304 Not Modified不带响应体浏览器继续使用本地缓存。这样服务端既不需要重新渲染页面也不需要在网络上重新传输页面内容两方面的开销同时被省去。在 Yii 2 中实现这一机制的组件就是yii\filters\HttpCache。它本质上是一个动作过滤器ActionFilter挂在控制器的behaviors()中即可生效仅对GET和HEAD请求起作用并能处理三种缓存相关的 HTTP 头Last-Modified—— 页面最后修改时间戳ETag—— 页面内容的实体标签哈希指纹Cache-Control—— 页面常规缓存策略启用 HttpCache 过滤器在控制器中声明行为即可启用public function behaviors() { return [ [ class yii\filters\HttpCache, only [index], lastModified function ($action, $params) { $q new \yii\db\Query(); return $q-from(post)-max(updated_at); }, ], ]; }这里用到的是ActionFilter提供的两个通用属性实现见 framework/base/ActionFilter.phponly过滤器仅作用于列出的动作 ID。不设置则作用于所有动作。except排除列表。若某动作同时出现在only与except中则不应用该过滤器。自 2.0.9 起动作 ID 支持通配符如site/*。HttpCache自身还有一个enabled属性framework/filters/HttpCache.php#L111默认为true可在运行时如调试模式、后台任务动态关闭缓存。Last-Modified头基于时间戳的缓存校验Last-Modified用时间戳标明页面自上次客户端缓存以来是否被修改。配置lastModified属性值应为 PHP callable即可开启/** * param Action $action 当前处理的动作对象 * param array $params “params” 属性的值 * return int 页面修改时的 Unix 时间戳 */ function ($action, $params)典型用法是查询数据表的updated_at最大值作为页面「最新修改时间」public function behaviors() { return [ [ class yii\filters\HttpCache, only [index], lastModified function ($action, $params) { $q new \yii\db\Query(); return $q-from(post)-max(updated_at); }, ], ]; }工作流程上述代码表明 HTTP 缓存只在index操作启用服务器基于帖子最后更新时间生成Last-Modified头。浏览器第一次访问index页时服务器正常生成页面并发送此后只要期间没有帖子被修改浏览器再次访问时服务器不会重新生成页面而是返回 304浏览器直接使用客户端缓存的版本。从源码看beforeAction()中会把这个时间戳格式化为标准的 HTTP 日期格式framework/filters/HttpCache.php#L148-L150$response-getHeaders()-set(Last-Modified, gmdate(D, d M Y H:i:s, $lastModified) . GMT);回调返回null时不会发送该头也不会产生 304 响应对应 CHANGELOG 中 no longer returns 304 HTTP code when callbacks return null 的修复。ETag头基于内容指纹的缓存校验Entity Tag实体标签用哈希值表示页面内容页面一旦修改哈希即改变。浏览器对比自己保存的哈希与服务器端生成的哈希即可判断页面是否变化。配置etagSeed属性值为 PHP callable返回用于生成哈希的种子字符串开启/** * param Action $action 当前处理的动作对象 * param array $params “params” 属性的值 * return string 一段种子字符用来生成 ETag 哈希值 */ function ($action, $params)示例——基于文章标题和内容生成 ETagpublic function behaviors() { return [ [ class yii\filters\HttpCache, only [view], etagSeed function ($action, $params) { $post $this-findModel(\Yii::$app-request-get(id)); return serialize([$post-title, $post-content]); }, ], ]; }工作流程HTTP 缓存只在view操作启用服务器根据所请求文章的标题与内容生成ETag头。首次访问正常渲染此后只要文章标题、内容未变服务器不重新生成页面浏览器使用缓存内容。ETag 生成算法与弱校验HttpCache内部将种子通过 SHA-1 生成强 ETagframework/filters/HttpCache.php#L209-L213protected function generateEtag($seed) { $etag . rtrim(base64_encode(sha1($seed, true)), ) . ; return $this-weakEtag ? W/ . $etag : $etag; }默认生成强 ETag…表示内容字节级一致自 2.0.8 起可配置weakEtag true生成弱 ETagW/…适用于内容语义等价但不必字节一致如 gzip 压缩差异的场景。HttpCacheTest中testGenerateEtag验证了强/弱 ETag 的前后缀格式tests/framework/filters/HttpCacheTest.php#L91-L125。选择简单、高效的种子表达式ETag 相比Last-Modified能实现更复杂、更精确的缓存策略。例如当站点切换主题时可以在种子里加入主题标识使所有 ETag 失效。但注意每次请求都必须重新计算 ETag复杂的种子生成逻辑会违背使用HttpCache的初衷带来不必要的性能开销。请尽量寻找一个能触发失效的最简表达式——比如上面示例中的serialize([$post-title, $post-content])就是一条低成本 SQL 加一次序列化。RFC 7232 关于两种头并存的规定Note: 为了遵循 RFC 7232HTTP 1.1 协议如果同时配置了ETag和Last-Modified头HttpCache将会同时发送它们。并且如果客户端同时发送If-None-Match头和If-Modified-Since头则只有前者会被接受。这一规则在validateCache()中落实framework/filters/HttpCache.php#L167-L178If-None-Match的优先级高于If-Modified-Since且支持多个 ETag 的比对——Request::getETags()会解析请求头中的多个 ETagframework/web/Request.php#L1711-L1718。HttpCacheTest::testValidateCache对两种头的优先级、精确匹配、通配符*等情况均有覆盖tests/framework/filters/HttpCacheTest.php#L54-L86。Cache-Control头定义常规缓存策略Cache-Control头指定页面的通用缓存策略如是否允许共享缓存、缓存有效期通过配置cacheControlHeader属性发送默认值为Cache-Control: public, max-age3600即「允许公共缓存有效期 1 小时」。可按需覆盖例如不希望 CDN 或代理缓存、只想让浏览器私有缓存[ class yii\filters\HttpCache, cacheControlHeader private, max-age600, ]注意该属性默认是字符串而非null因此每次请求都会发送Cache-Control头若设置为null则不发送见 framework/filters/HttpCache.php#L96 与sendCacheControlHeader()的实现 framework/filters/HttpCache.php#L184-L202。会话缓存限制器解决与 Session 的冲突当页面使用 Session 时PHP 会按照php.ini中session.cache_limiter的设置自动发送一些缓存相关 HTTP 头如Expires、Cache-Control、Pragma、Last-Modified。这些头可能干扰甚至使你的HttpCache失效——比如默认的nocache限制器会发送禁止缓存的头导致Cache-Control: public无法生效。默认行为HttpCache的sessionCacheLimiter属性默认为空字符串表示完全禁止 PHP 自动发送这些缓存头源码中通过header_remove()移除Expires、Cache-Control、Last-Modified、Pragma实现framework/filters/HttpCache.php#L186-L195。自定义行为若想改变可将该属性设为以下字符串值之一取值含义依据 PHP 手册session_cache_limiter()public允许公共共享缓存适合公开内容private仅允许浏览器私有缓存代理不可缓存private_no_expire同private但不发送Expires头nocache禁止一切缓存若将该属性设为null则HttpCache完全不管 Session 缓存头PHP 按session.cache_limiter配置自行发送。参考 PHP 手册 缓存限制器 了解各值的详细含义。缓存校验的完整流程源码级综合 framework/filters/HttpCache.php#L117-L157 的beforeAction()实现一次带缓存的请求处理如下前置检查enabled为false、请求方法不是GET/HEAD、或lastModified与etagSeed均为null时直接放行不做任何缓存处理计算缓存验证信息依次调用lastModified回调获得时间戳、调用etagSeed回调获得种子null时跳过再经generateEtag()生成 ETag发送Cache-Control头并按需处理 Session 缓存限制器发送ETag头若生成了校验缓存有效性validateCache()优先看If-None-Match与请求携带的 ETag 集合逐一精确比较其次看If-Modified-Since与Last-Modified时间戳比较只有当Last-Modified存在且缓存有效但无 ETag 时才发送Last-Modified头符合 RFC 7232 第 4.1 节命中缓存设置状态码304并返回false终止后续动作执行——控制器动作、视图渲染、响应体传输全部跳过。Response组件对 304 响应会剔除消息体见 framework/web/Response.php#L1102-L1103。因此可以这样理解成本收益启用 HttpCache 后未命中缓存时多付出的是计算一次时间戳/种子的代价通常是一条轻量 SQL 或一次序列化命中缓存时省下的是整个动作执行 视图渲染 页面传输的全部开销。这也是原文档强调「种子表达式要尽量简单」的原因。SEO 影响搜索引擎的爬虫趋向于遵循站点的缓存头。由于部分爬虫对同一域名在单位时间内的抓取页面数有限制启用缓存头可以减少重复请求数量让爬虫在有限配额内抓到更多页面从而提升站点被索引的效率。一个合理的缓存策略例如对不常变化的列表页设置public, max-age3600并配合 ETag/Last-Modified 做条件请求对用户体验与 SEO 都是加分项。小结HttpCache是 Yii 2 提供客户端缓存的标准方案通过behaviors()声明、only/except限定动作仅作用于GET/HEAD请求lastModified与etagSeed是两个 callable 属性分别驱动时间戳与内容指纹两种缓存校验二者可同时启用并遵循 RFC 7232 的优先级规则cacheControlHeader控制通用缓存策略默认public, max-age3600sessionCacheLimiter解决与 Session 自动缓存头的冲突缓存命中时以 304 响应提前终止动作执行服务端渲染与内容传输同时省去相关实现与测试可深入阅读 framework/filters/HttpCache.php、tests/framework/filters/HttpCacheTest.php以及 缓存概览 与 过滤器指南 获取完整上下文。赞分享后端Web框架【免费下载链接】yii2Yii 2: The Fast, Secure and Professional PHP Framework项目地址https://gitcode.com/gh_mirrors/yi/yii2点击查看免费下载相关推荐Yii 2 HTTP 缓存实战指南用 HttpCache 过滤器实现客户端缓存Last-Modified / ETag / Cache-ControlYii 2 HTTP 缓存实战指南用 HttpCache 过滤器实现客户端缓存Last Modified / ETag / Cache Control H后端Web框架Yii 2 HTTP 缓存HttpCache实战指南Last-Modified、ETag 与 Cache-Control 客户端缓存机制详解Yii 2 HTTP 缓存HttpCache实战指南Last Modified、ETag 与 Cache Control 客户端缓存机制详解 HTTP 缓后端Web框架Yii2 HTTP 缓存实战借助 HttpCache 过滤器实现 Last-Modified、ETag 与 Cache-Control 客户端缓存Yii2 HTTP 缓存实战借助 HttpCache 过滤器实现 Last Modified、ETag 与 Cache Control 客户端缓存 导读 本指后端Web框架上一篇5个annyang.js命令别名与同义词处理技巧让语音识别更智能下一篇Scrutiny与Prometheus集成构建完整的监控生态体系创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
TSMC 0.18um下1.5GHz Fractional PLL的Cadence+ADS协同设计 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 14:09:10
【Dv3Admin】菜单转换选项卡平铺到页面 在多业务模块项目中,菜单与路由的统一管理对前后端协作和功能扩展至关重要。缺乏规范会导致组件路径混乱、权限控制分散,增加维护难度。
基于统一规则的路由与组件路径配置方案,结合后端动态路由数据输出与前端通用组件渲染机制,实现多业务模块下的可扩展菜单管理和工作台… · 2026/9/24 14:08:58
MiniScript 版《Horserace》移植实战解析:赛道渲染、赔率引擎与跨平台运行 示例工程 【免费下载链接】basic-computer-games An updated version of the classic "Basic Computer Games" book, with well-written examples in a variety of common MEMORY SAFE, SCRIPTING programming languages. See https://coding-horror.github.io/basic… · 2026/9/24 14:08:57
Genex词法分析器深度解析:状态机如何精准切分复杂规则文本 Genex词法分析器深度解析:状态机如何精准切分复杂规则文本 【免费下载链接】genex-cj 生成表达式(Generate Expression,简称:Genex或GE)是一款用于按照指定语法规则随机或固定生成数据的功能库。主要适用于依赖规则数据… · 2026/9/24 16:39:56
PaddleHub 语言模型(Language Model)模块实战指南:词嵌入、语义匹配与预训练语义模型全解析 人工智能大模型微调模型推理服务 【免费下载链接】PaddleFormers PaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle. 项目地址: https://gitcode.com/gh_mirrors/pa/PaddleFormers 点击查看 免费下载 本指… · 2026/9/24 16:39:56
RollingGo MCP 两种接入方式对比指南 技术团队在选择RollingGo MCP 接入方案时,需要根据业务阶段(MVP 验证 vs. 生产级应用)和用户体验要求(跳转支付 vs. Agent 内闭环)来做出判断。本文从功能、技术实现、适用场景等维度对两种方案进行对比,帮… · 2026/9/24 16:39:50
Embassy nRF91 蜂窝调制解调器网络驱动:embassy-net-nrf91 集成与实践 嵌入式物联网异步编程 【免费下载链接】embassy Modern embedded framework, using Rust and async. 项目地址: https://gitcode.com/gh_mirrors/em/embassy 点击查看 免费下载 导读
embassy-net-nrf91 是 Embassy 生态中面向 Nordic nRF91 系列蜂窝调制解调器&am… · 2026/9/24 16:39:50
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44