应使用 map 指令将 ua 归一化为 mobile/desktop,proxy_cache_key 中显式加入 $device,同步设置 add_header x-device-type $device 和 vary "x-device-type",并避免使用实时变量,刷新缓存需基于完整 key。

要让 Nginx 的 proxy_cache_key 正确区分手机端和 PC 端内容,核心不是“识别 UA”,而是“提取稳定、语义明确的设备类型”,并确保该维度真实影响后端响应——否则缓存分离就失去意义,反而降低命中率。
用 map 提取标准化设备标识
别直接拼 $http_user_agent,它太长、易变、含大量无意义字段。应在 http 块中用 map 指令归一化为几个固定值:
map $http_user_agent $device {- ~*"(iPhone|iPad|iPod|Android)" "mobile";
- ~*"(Windows NT|Mac OS X|Linux)" "desktop";
- default "desktop";
- }
这样所有 iOS/Android 设备统一标为 mobile,桌面系统统一为 desktop,避免因 UA 微小差异(如 Chrome 版本号、微信内置浏览器标记)导致缓存分裂。
在 proxy_cache_key 中显式加入 $device
在对应需要区分终端的 location 块中,把 $device 加入缓存键,例如:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args:$device";- 若还需隔离登录态,可追加:
:$cookie_user_id(未登录时设为"guest") - 若页面还按语言区分,再加:
:$http_accept_language(建议只取主语言,如zh或en)
注意:键中不要包含 $request_time、$msec 这类实时变量,否则缓存永远不命中。
同步配置 Vary 响应头(尤其对接 CDN 时)
仅改 proxy_cache_key 不够,CDN 和浏览器需知道“这个响应依赖设备类型”。必须添加:
add_header Vary "X-Device-Type";- 同时在后端或 Nginx 中设置该 header:
add_header X-Device-Type $device;
这样 CDN 才会将 mobile 和 desktop 视为两个独立缓存分支,而不是靠 URL 硬拆。
验证与清理机制要配套
一旦 $device 进入缓存键,就不能再用“按 URL 刷新”功能:
- 刷新操作必须基于完整 cache key,例如:
api_v2:https://example.com/home:mobile - 建议在 key 开头加业务前缀(如
"web_v1:"),便于批量识别和 purge - 上线前用
curl -I检查响应头是否含Vary: X-Device-Type,并确认不同 UA 请求返回的X-Cache: HIT/MISS行为符合预期










