文档

请求通过CDN回源后Gzip压缩不生效?

更新时间:

问题描述

CDN源站是Nginx服务器,开启了Gzip压缩功能,当客户端直接请求源站时,Gzip压缩功能正常;当客户端的请求回源时,Gzip压缩功能失效,详情如下:

支持Gzip压缩/解压缩时,Nginx将返回压缩后的内容,以降低流量开销,加快响应速度。但是启用CDN后,请求将通过CDN进行转发,而客户端最终收到的是未压缩的内容,即CDN回源后,源站的Gzip功能未生效,详情如下:

  • 未启用CDN 请求头(Request Header)含有Accept-Encoding: gzip, deflate,响应头(Response Header)正常返回Content-Encoding: gzip,即内容已经被压缩。

  • 启用CDN后 请求头含有Accept-Encoding: gzip, deflate,但响应头返回的是Content-Length,并未响应Content-Encoding: gzip

问题原因

源站Nginx服务器中Gzip相关配置错误,CDN的回源请求未启用Gzip压缩功能,详情如下:

客户端请求经过CDN转发至源站时,回源的请求头中将增加Via字段以标识请求来自代理服务器(此处指CDN)。而Nginx的ngx_http_gzip_module模块中存在一个gzip_proxied配置,此配置专门用于控制代理服务器的请求是否启用Gzip压缩,并且此配置生效的前提之一是请求头中含有Via字段。由此可见,gzip_proxied配置将决定回源的请求是否启用Gzip压缩。

解决方案

如果您遇到的问题与问题描述中的情况完全一致,则可以参考下列步骤更新Nginx的配置文件,以修复此问题。如果您无法确定问题现象,可参见更多信息进行排查。

  1. 找到Nginx中含有Gzip的配置段。由于Gzip可配置在http、server、location三个配置段中,不同配置段对应的配置文件可能不同,请您以实际配置情况为准,本文以Gzip配置在nginx.conf文件的HTTP配置段为例。

  2. 检查Gzip配置中是否存在gzip_proxied配置。如果存在,则修改为以下配置;如果不存在,则添加以下配置。更多有关gzip_proxied配置的介绍,请参见Nginx的官方文档

    说明

    当不存在gzip_proxied配置时,该配置将使用默认值off

    gzip_proxied  any
    说明

    any表示所有来自代理服务器的请求都将启用压缩。

  3. 保存上述配置后,依次执行下列命令,确认Nginx配置无误,然后重新加载Nginx配置文件。

    nginx -t
    nginx -s reload
  4. 启用CDN,客户端请求经过CDN转发至源站Nginx服务器后,确认返回的响应头中含有Content-Encoding: gzip,即内容被压缩。

更多信息

为确保现场环境中的问题情况与本文的问题描述一致,请参见下列步骤进行测试:

  1. 登录任意支持curl命令的客户端。

  2. 参考下列命令,通过curl命令直接访问源站,同时增加含有Accept-Encoding: gzip, deflate的请求头。

    curl -voa 'http://[$Domain]/[$Resource]' -x [$Original_Server_IP]:80 -H 'Accept-Encoding: gzip, deflate'
    说明
    • [$Domain]:您的域名。

    • [$Resource]:网站里某个资源的请求地址,例如一张图片、一个API接口等。

    • [$Original_Server_IP]:源站Nginx服务器的公网IP地址。

    系统返回类似如下,确认响应头中含有Content-Encoding: gzip

  3. 参考下列命令,在步骤2命令的基础上,增加一个Via字段,模拟请求来自于代理服务器。

    curl -voa 'http://[$Domain]/[$Resource]' -x [$Original_Server_IP]:80 -H 'Accept-Encoding: gzip, deflate' -H 'Via:xxx'
    说明

    Via字段使用任意值均可,不影响测试结果,本文以xxx为例。

    系统返回类似如下,确认响应头中返回的是Content-Length,并未响应Content-Encoding: gzip