首发:【开发日记】使用 Nginx 直接部署 gzip 压缩的静态资源文件
在正常情况下,我们会将未压缩的 HTML
、CSS
、JS
文件部署到 Nginx 服务器上,并通过开启 gzip
模块,在访问时由 Nginx 对这些静态资源进行动态压缩,浏览器接收到文件后根据响应头中的 Content-Encoding: gzip
解压,再通过 Content-Type
进行渲染。
而本文要介绍一种 “不走寻常路” 的做法,我们不再依赖 Nginx 的动态压缩功能,而是直接将手动压缩好的 .gz
文件放在服务器上,让 Nginx 直接将这些 .gz
文件返回给浏览器。这种方式有如下优点:
① 减少服务器 CPU 占用(不需要动态压缩)
② 降低服务器磁盘使用量
③ 响应速度更快
下面动手实践一下。
第一步:了解 gzip_static 配置
首先查看 Nginx 是否支持该操作,参考官方文档:
🔗 https://nginx.org/en/docs/http/ngx_http_gzip_static_module.html
Nginx 的 gzip_static
属性有三个值:
off
:关闭(默认)on
:如果请求的是.html
,且存在.html.gz
文件,则返回.gz
文件always
:不管客户端是否支持 gzip,都返回.gz
文件
⚠️ 我尝试开启 gzip_static on
和 always
,但浏览器返回了 403 错误,说明 Nginx 找不到对应的 .gz
文件。
第二步:设置 index 指向 .gz
文件
403 的原因是 Nginx 默认查找的是 index.html
,但我们只有 index.html.gz
。
于是添加配置:
index index.html index.html.gz;
重启 Nginx 后,浏览器找到了 index.html.gz
,但弹出了下载框,Nginx 将其作为压缩包返回了。
第三步:告诉浏览器这是 gzip 格式
把gz
文件下载下来不行,再一看请求的响应头中并没有content-encoding
属性,本文一开头说了浏览器会通过该属性的gzip
属性值解压静态文件去渲染,为该请求添加响应头标识返回结果是一个gzip
:
add_header Content-Encoding gzip;
再次重启 Nginx,浏览器不再下载 .gz
文件,而是显示了解压后的内容。不过它只是以纯文本方式显示了 HTML 内容,并没有像网页那样渲染。
第四步:设置正确的 Content-Type 类型
根据本文开头时写的内容,浏览器对gz
文件解压完后会去查看响应头的content-type
属性,根据该属性去渲染静态资源。此时检查响应头如下所示:
浏览器把解压后的文件作为文本处理了,那不行啊,得让浏览器把它作为html渲染,告诉浏览器如果请求.html.gz
格式的文件时让作为HTML去渲染。
location ~ \.html\.gz$ {
default_type text/html;
}
重启Nginx后再次访问,完美解决。
最终 Nginx 配置
server {
listen 80;
server_name test.cn;
root /work/html/test;
include /etc/nginx/mime.types;
add_header Content-Encoding gzip;
index index.html index.html.gz;
location ~ \.css\.gz$ {
default_type text/css;
}
location ~ \.html\.gz$ {
default_type text/html;
}
}
如果也需要使用gzip
对CSS进行压缩存储,在index.html
中引用CSS时,需要直接引用index.css.gz
。