需先归一化User-Agent:用map指令按iPhone/iPad/Android(非平板)→mobile,Windows NT等→desktop,再将$device变量纳入proxy_cache_key与Vary头,确保缓存键与响应头严格对齐。

要实现 Nginx proxy_cache 按设备类型(移动端/PC)独立缓存,核心不是把原始 User-Agent 直接塞进缓存键,而是先归一化识别、再统一打标、最后让缓存键与响应头严格对齐。
用 map 归类 UA,生成稳定设备变量
在 http 块顶层定义映射,把千变万化的 UA 字符串压缩为有限语义类别:
- 优先匹配高区分度特征:含
iPhone、iPad→mobile;含Android且非平板 UA →mobile;含Windows NT或且无移动关键词 → <code>desktop - 兜底必须明确,例如:
default "desktop",避免变量为空导致缓存键异常 - 变量名要合法且全局一致,比如定义为
$device_type,后续所有地方都用它
同步配置 Vary 响应头和 proxy_cache_key
Vary 和缓存键必须一一对应,缺一不可:
- 在
location块中加:add_header Vary "Device-Type" always;——always确保 404、304 等响应也带该头,防止 CDN 或代理节点行为不一致 -
proxy_cache_key必须包含$device_type,例如:"$scheme$request_method$host$request_uri$device_type" - 如果还依赖其他头(如
$http_origin),Vary 和 cache_key 都得同步体现,否则隔离失效
避免默认 key 导致缓存碎片化
Nginx 默认 proxy_cache_key 包含完整 $request_uri(含 query 参数)和全部请求头,极易造成同一页面因参数微小差异生成大量无效缓存项:
- 静态资源通常无需按参数区分,显式剔除干扰项:不用
$args,也不把$http_cookie或$http_referer加入 key - 若需支持登录态差异化(如会员/游客),应提取稳定标识(如
map $cookie_sessionid $cache_user_role { ... default "guest"; }),而非直接用原始 Cookie
验证是否生效的两个关键点
用 curl 发起两次不同设备类型的请求:
- 模拟 iPhone 请求:
curl -I -H "User-Agent: Mozilla/5.0 (iPhone..." https://yoursite.com/,确认响应头含Vary: Device-Type且值为mobile - 模拟 Chrome 桌面请求,确认
Vary头相同、Device-Type值为desktop - 观察
X-Cache或X-Upstream-Cache-Status:相同设备第二次请求应为HIT,不同设备间应为MISS,说明缓存已按设备类型正确隔离


















