如何通过sub_filter指令在代理层动态调整CDN加速链接缓存内容?
- 内容介绍
- 文章标签
- 相关推荐
本文共计732个文字,预计阅读时间需要3分钟。
使用Nginx的`sub_filter`指令可以实现在反向代理响应返回给客户端前,对HTML、CSS、JS等文本内容进行实时字符串替换,从而将缓存中的硬编码CDN域名动态替换为当前请求所使用的CDN域名(或回源域名),实现一域名缓存、多套CDN配置的灵活部署。
启用 sub_filter 并确保响应可修改
Nginx 默认不缓存带 Vary 头或压缩过的响应,且 sub_filter 仅作用于未压缩的文本响应。需确保:
- 后端响应未启用
gzip或已配置sub_filter兼容 gzip(通过gzip off或gunzip on+gzip_http_version 1.0) - 禁用
ETag或设置etag off,避免因内容变更导致 ETag 不一致而绕过缓存 - 确保
Content-Type匹配目标类型(如text/html、text/css),必要时用sub_filter_types扩展支持类型
按 Host 或请求头动态选择替换目标
sub_filter 本身不支持变量,但可通过 map 指令预定义替换规则,结合 set 或 if 实现条件化:
- 用
map $host $cdn_domain将不同域名映射到对应 CDN 地址(如site-a.com → cdn-a.example.com) - 在
location中引用该变量:sub_filter "//cdn.example.com" "//$cdn_domain"; - 若需更细粒度控制(如按请求头
X-CDN-Provider切换),同样用map解析并赋值
处理相对路径与协议相对 URL
缓存内容中常见 //cdn.example.com/xxx(协议相对)或 /static/xxx(绝对路径)。建议统一策略:
- 优先匹配协议相对链接:
sub_filter "//cdn.example.com" "//$cdn_domain"; - 对根路径资源,可额外添加规则替换
src="/static/→src="https://$cdn_domain/static/,注意引号和空格边界 - 避免过度替换:用
sub_filter_once off允许多次匹配,但需加sub_filter_last_modified off防止 Last-Modified 头被误改
与 proxy_cache 协同工作注意事项
缓存内容被修改后,响应体已变化,但默认情况下 Nginx 不会自动更新缓存哈希或校验值,需注意:
-
sub_filter修改的是出方向响应,不影响缓存键(proxy_cache_key),因此同一缓存项可能被不同域名复用并反复替换——这正是预期行为 - 若需隔离缓存(如每个 CDN 域名独享缓存),应在
proxy_cache_key中加入$cdn_domain变量 - 务必开启
sub_filter_last_modified off,否则修改响应体后可能导致Last-Modified头与实际内容不一致
本文共计732个文字,预计阅读时间需要3分钟。
使用Nginx的`sub_filter`指令可以实现在反向代理响应返回给客户端前,对HTML、CSS、JS等文本内容进行实时字符串替换,从而将缓存中的硬编码CDN域名动态替换为当前请求所使用的CDN域名(或回源域名),实现一域名缓存、多套CDN配置的灵活部署。
启用 sub_filter 并确保响应可修改
Nginx 默认不缓存带 Vary 头或压缩过的响应,且 sub_filter 仅作用于未压缩的文本响应。需确保:
- 后端响应未启用
gzip或已配置sub_filter兼容 gzip(通过gzip off或gunzip on+gzip_http_version 1.0) - 禁用
ETag或设置etag off,避免因内容变更导致 ETag 不一致而绕过缓存 - 确保
Content-Type匹配目标类型(如text/html、text/css),必要时用sub_filter_types扩展支持类型
按 Host 或请求头动态选择替换目标
sub_filter 本身不支持变量,但可通过 map 指令预定义替换规则,结合 set 或 if 实现条件化:
- 用
map $host $cdn_domain将不同域名映射到对应 CDN 地址(如site-a.com → cdn-a.example.com) - 在
location中引用该变量:sub_filter "//cdn.example.com" "//$cdn_domain"; - 若需更细粒度控制(如按请求头
X-CDN-Provider切换),同样用map解析并赋值
处理相对路径与协议相对 URL
缓存内容中常见 //cdn.example.com/xxx(协议相对)或 /static/xxx(绝对路径)。建议统一策略:
- 优先匹配协议相对链接:
sub_filter "//cdn.example.com" "//$cdn_domain"; - 对根路径资源,可额外添加规则替换
src="/static/→src="https://$cdn_domain/static/,注意引号和空格边界 - 避免过度替换:用
sub_filter_once off允许多次匹配,但需加sub_filter_last_modified off防止 Last-Modified 头被误改
与 proxy_cache 协同工作注意事项
缓存内容被修改后,响应体已变化,但默认情况下 Nginx 不会自动更新缓存哈希或校验值,需注意:
-
sub_filter修改的是出方向响应,不影响缓存键(proxy_cache_key),因此同一缓存项可能被不同域名复用并反复替换——这正是预期行为 - 若需隔离缓存(如每个 CDN 域名独享缓存),应在
proxy_cache_key中加入$cdn_domain变量 - 务必开启
sub_filter_last_modified off,否则修改响应体后可能导致Last-Modified头与实际内容不一致

