You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Varnish缓存ESI组件浏览器不生效,Cookie相关问题及替代方案咨询

问题分析与解决方案

核心问题

你的ESI组件在Varnish端能命中缓存(无Cookie的curl请求返回HIT),但浏览器端不缓存,修改内容后立即获取新值,核心原因大概率是浏览器请求携带Cookie:

  • 即便后端返回Cache-Control: public,浏览器对带Cookie的请求会默认采取保守策略,可能跳过本地缓存直接发起请求;
  • 默认情况下Varnish会跳过带Cookie的请求缓存,导致每次浏览器请求都回源,自然无法触发本地缓存。

是否需要移除ESI请求的Cookie?

如果你的ESI组件不依赖用户会话信息(比如通用导航栏、静态内容块),强烈建议移除ESI请求的Cookie:
这既能让Varnish缓存统一的组件版本,也能让浏览器正常遵守max-age规则进行本地缓存。

Varnish配置示例(vcl_recv阶段)

sub vcl_recv {
    # 匹配ESI组件的URL规则,比如以/esi/开头
    if (req.url ~ "^/esi/") {
        unset req.http.Cookie;
    }
}

无需清除Cookie的缓存方案

如果组件必须依赖Cookie(比如显示用户专属内容),可以通过以下方式实现缓存:

  1. 添加Vary: Cookie响应头
    后端需要在响应头中补充Vary: Cookie,告知Varnish和浏览器:组件内容依赖Cookie值,需按不同Cookie缓存不同版本。
    示例后端代码:

    header('Vary: Accept-Encoding, Cookie');
    
  2. 配置Varnish允许带Cookie请求的缓存
    默认Varnish会跳过带Cookie的请求缓存,需在vcl_recv中明确允许缓存该类请求:

    sub vcl_recv {
        if (req.url ~ "^/esi/" && req.http.Cookie) {
            # 允许缓存带Cookie的ESI请求
            set req.http.Cache-Control = "public";
        }
    }
    
  3. 确保浏览器缓存规则生效
    打开浏览器开发者工具的「网络」面板检查:

    • 确认组件请求的响应头中Cache-Control完整包含public, max-age=300等规则;
    • 确认没有no-cache、no-store这类禁用缓存的指令被意外添加。

额外排查点

  • 确认Varnish已开启ESI解析:在vcl_backend_response中添加beresp.do_esi = true;(当响应包含ESI标签时自动解析);
  • 查看组件请求的「请求头」确认是否携带Cookie,同时检查「响应头」中的缓存相关字段是否正确返回。

内容的提问来源于stack exchange,提问作者Andrii Sukhoi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:17:20