codeigniter 4 默认不设置cache-control响应头,需用response::setcache()显式配置;服务端缓存与http响应缓存无关;静态资源应由web服务器而非框架处理;带查询参数的url易导致缓存失效。

CodeIgniter 4 的 Cache-Control 响应头默认不生效
CodeIgniter 4 默认不会自动设置 Cache-Control 响应头,哪怕你调用了 $this->cache->save(),也只是缓存了数据,跟 HTTP 响应缓存无关。这是最容易混淆的点:数据缓存 ≠ 响应缓存。
- 响应缓存要靠控制器里显式设置头信息,或使用
Response类的setCache()方法 -
$this->cache->save()存的是服务端缓存(如文件、Redis),不影响浏览器是否重新请求 - 若没手动设置,每次请求都会走完整生命周期,哪怕内容完全不变
用 Response::setCache() 启用标准响应缓存
这是最直接、也最符合 HTTP 协议的方式。它会同时设置 Cache-Control、Expires 和 ETag(可选)。
- 在控制器方法末尾调用:
$this->response->setCache(['max-age' => 3600, 'etag' => false]); -
max-age是核心参数,单位秒;设为0表示禁止缓存,3600表示 1 小时内浏览器可直接用本地副本 -
etag默认为true,会基于响应体生成哈希值;若响应体动态但结构固定(如 JSON API),建议关掉避免误判 - 注意:该方法必须在响应发送前调用,放在
return view()或echo之后无效
静态资源(CSS/JS)别依赖框架缓存,走 Web 服务器配置
CodeIgniter 不该处理 CSS、JS、图片这类静态文件的缓存逻辑——既低效又绕过 Nginx/Apache 的优化能力。
- 确保这些文件不在
public/index.php路由范围内,而是直接由 Web 服务器提供 - Nginx 示例配置片段:
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; } - 如果用
asset()辅助函数生成路径,确认它输出的是真实 URL(如/assets/css/app.css),而非经 PHP 路由转发的路径 - 否则浏览器可能收到
Cache-Control: no-cache(来自 CI 默认响应头),导致反复请求
带查询参数的 URL 缓存容易失效
像 /api/items?sort=name&page=2 这类 URL,即使内容相同,不同参数组合会被视为不同缓存条目,且浏览器/CDN 通常不缓存带参数的 GET 请求(除非明确声明)。
- 前端尽量用 POST + JSON body 替代长查询参数,或对参数做标准化(如统一排序 key 名)
- 后端可在
setCache()前手动计算 ETag 时忽略无关参数:md5($content . $sort),而不是整个$_SERVER['QUERY_STRING'] - CDN(如 Cloudflare)默认不缓存带查询参数的请求,需在页面规则中显式开启 “Cache Everything” 并勾选 “Cache Query String”
缓存逻辑一旦混用服务端存储、响应头、Web 服务器和 CDN 层,就很容易出现“明明设了 1 小时,却每次都刷新”的情况。关键是分清每层职责:CI 管响应头,Nginx 管静态文件,CDN 管边缘缓存,别让它们互相覆盖或静默失效。










