尽管遵循官方Nginx文档/在线研究,但Nginx gzip压缩无法正常工作

3

问题

我已经快要绝望了,所以决定发布一个询问。我正在尝试在 nginx docker 容器上设置 gzip 压缩,因为我注意到 Lighthouse 抱怨我的一些客户站点没有启用它。所有有问题的站点都在它们的配置中添加了正确的设置和类型的 gzip 压缩设置,但无论我如何更改设置,它都不会压缩。我已经通过浏览器和使用 CURL 请求来测试过这个问题,但是没有任何变化。

我查看了许多票据,包括这里和其他地方的票据,尽管对配置进行了很多调整,但没有解决方案起作用。

我尝试过的方法

出于此票证和测试目的,我创建了一个完全“原始”的 docker 项目,其中包含一个 default.conf 文件,其中包含站点配置和一个 public/ 文件夹,其中包含一个 index.htmltest-css.css 文件。

您可以在此处找到此示例项目:https://github.com/MajorFailz/so-issue-nginx-docker-example

配置文件仅服务于该文件夹,并包含 nginx 自己的文章中推荐的 gzip 设置:https://docs.nginx.com/nginx/admin-guide/web-server/compression/

Dockerfile

FROM nginx:1.21

RUN mkdir /app

WORKDIR /app

COPY ./public /app/public

COPY ./conf/default.conf /etc/nginx/conf.d/default.conf

default.conf

server {
    gzip on;
    gzip_types      text/plain application/xml text/css;
    gzip_proxied    no-cache no-store private expired auth;
    gzip_min_length 1000;

    location / {
        root /app/public;
    }
}

使用浏览器进行测试

当启动该项目并在Chrome中查看index.html时,打开开发选项卡并查看index.html时,可以发现它正在使用gzip压缩进行服务:

Example showing index.html in developer console

现在如果我们查看test-css.css文件,我们会发现它没有被压缩:

Example showing test-css.css file without compression

通过控制台进行测试

因此,在进行一些研究后,似乎有时Chrome或各种Windows杀毒软件会在到达浏览器之前对其进行解压缩。因此,我尝试使用curl从Linux虚拟机中获取带有gzip的文件并查看其内容。

master@apex:~$ curl -H "Accept-Encoding: gzip" -I http://www.apex.local/test-css.css
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Tue, 11 Jan 2022 15:38:00 GMT
Content-Type: text/css
Content-Length: 53790
Connection: keep-alive
Last-Modified: Tue, 11 Jan 2022 14:55:59 GMT
ETag: "61dd9a7f-d21e"
Accept-Ranges: bytes

仍然没有压缩!因此,它似乎不是浏览器的问题,此外我使用了一个网站性能报告网站来测试它,遇到了同样的问题。

经过进一步的研究,如果nginx没有安装gzip模块,则会出现问题,因此在挖掘后,我从容器内部运行了此命令,该命令测试是否已编译gzip:

root@127b59858b48:/app# 2>&1 nginx -V | tr -- - '\n' | grep _module | grep gzip
http_gzip_static_module

它有这个模块!那么这意味着什么?

附加信息

我尝试了许多不同的配置设置,也尝试了不同的操作系统设置来运行nginx docker镜像(我的项目在alpine上运行,所以认为可能是一个因素),但结果始终如一。

客户端nginx配置示例

以下是从客户网站复制/粘贴的当前配置示例:

    gzip on;
    gzip_min_length 10240;
    gzip_comp_level 1;
    gzip_vary on;
    gzip_disable msie6;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types
        # text/html is always compressed by HttpGzipModule
        text/css
        text/javascript
        text/xml
        text/plain
        text/x-component
        application/javascript
        application/x-javascript
        application/json
        application/xml
        application/rss+xml
        application/atom+xml
        font/truetype
        font/opentype
        application/vnd.ms-fontobject
        image/svg+xml;

参考票据

我查看了许多票据,但这是我仍然在浏览器中打开的三个最近的票据:

2个回答

2

一切在我的Debian 11主机上正常运行

$:/so-issue-nginx-docker-example# curl -Iv -H "Accept-Encoding: gzip" 127.1:49153/test-css.css
*   Trying 127.0.0.1:49153...
* Connected to 127.1 (127.0.0.1) port 49153 (#0)
> HEAD /test-css.css HTTP/1.1
> Host: 127.1:49153
> User-Agent: curl/7.74.0
> Accept: */*
> Accept-Encoding: gzip
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: nginx/1.21.5
Server: nginx/1.21.5
< Date: Wed, 12 Jan 2022 09:12:35 GMT
Date: Wed, 12 Jan 2022 09:12:35 GMT
< Content-Type: text/css
Content-Type: text/css
< Last-Modified: Wed, 12 Jan 2022 09:04:47 GMT
Last-Modified: Wed, 12 Jan 2022 09:04:47 GMT
< Connection: keep-alive
Connection: keep-alive
< ETag: W/"61de99af-d21e"
ETag: W/"61de99af-d21e"
< Content-Encoding: gzip
Content-Encoding: gzip


我注意到你的浏览器和curl中NGINX版本都是1.18.0。你分享的Dockerfile使用的是NGINX版本1.21。考虑到这一点,你确定你正在将curl发送到正确的实例吗?还是在到达“Docker化”NGINX之前有其他NGINX服务器代理流量?
请再仔细检查一下。我将使用1.18测试设置,以确保不是版本问题。
更新:它也适用于1.18.0。
HTTP/1.1 200 OK
< Server: nginx/1.18.0
Server: nginx/1.18.0
< Date: Wed, 12 Jan 2022 09:52:00 GMT
Date: Wed, 12 Jan 2022 09:52:00 GMT
< Content-Type: text/css
Content-Type: text/css
< Last-Modified: Wed, 12 Jan 2022 09:04:47 GMT
Last-Modified: Wed, 12 Jan 2022 09:04:47 GMT
< Connection: keep-alive
Connection: keep-alive
< ETag: W/"61de99af-d21e"
ETag: W/"61de99af-d21e"
< Content-Encoding: gzip
Content-Encoding: gzip


你是传奇,我的本地开发环境和客户站点都通过主机服务器上的单独nginx实例代理docker nginx连接,因此它在docker实例上被压缩,然后在主机上解压缩,再解压缩并发送回来。有时只需要另一对眼睛,感谢您抽出时间来研究这个问题,您让我避免了彻底疯狂。可能值得提醒其他像我这样的蠢蛋将此添加到您的答案中。 - MajorFailz

0
如果您在启用gzip压缩后,在浏览器的响应头中缺少“Content-Encoding:gzip”,请尝试单击开发人员工具中的“禁用缓存”复选框。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接