10

我们有一个Node/expressWeb 应用程序,它通过express.static(). nginx它前面有一个服务器,当前配置为gzip这些静态资产请求,如果user agent可以的话。

但是,尽管按预期nginx执行,但它正在从原点删除标头,并改为设置。这会破坏我们的.gzipContent-LengthTransfer-Encoding: chunkedCDN

JS以下是来自节点后端和来自的典型静态资产请求(在本例中为文件)的响应nginx

要求

curl -s -D - 'http://my_node_app/res/my_js.js' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Connection: keep-alive' --compressed -o /dev/null

来自 Node 的响应标头

HTTP/1.1 200 OK
Accept-Ranges: bytes
Date: Wed, 07 Jan 2015 02:24:55 GMT
Cache-Control: public, max-age=0
Last-Modified: Wed, 07 Jan 2015 01:12:05 GMT
Content-Type: application/javascript
Content-Length: 37386   // <--- The expected header
Connection: keep-alive

来自 nginx 的响应标头

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 07 Jan 2015 02:24:55 GMT
Content-Type: application/javascript
Transfer-Encoding: chunked  // <--- The problematic header
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: public, max-age=0
Last-Modified: Wed, 07 Jan 2015 01:12:05 GMT
Content-Encoding: gzip

我们当前nginx的静态资产配置location如下所示:

nginx 配置

# cache file paths that start with /res/
location /res/ {
    limit_except GET HEAD { }

    # http://nginx.com/resources/admin-guide/caching/
    # http://nginx.org/en/docs/http/ngx_http_proxy_module.html

    proxy_buffers 8 128k;
    #proxy_buffer_size 256k;
    #proxy_busy_buffers_size 256k;

    # The cache depends on proxy buffers, and will not work if proxy_buffering is set to off.
    proxy_buffering     on;
    proxy_http_version  1.1;
    proxy_set_header  Connection "";
    proxy_connect_timeout  2s;
    proxy_read_timeout  5s;
    proxy_pass          http://node_backend;

    chunked_transfer_encoding off;

    proxy_cache         my_app;
    proxy_cache_valid   15m;
    proxy_cache_key     $uri$is_args$args;
}

从上面的配置中可以看出,即使我们chunked_transfer_encoding off根据nginx文档明确设置了这样的路径, haveproxy_buffering on和 have a big enough proxy_buffers size,响应仍然被分块。

我们在这里缺少什么?

--编辑1:版本信息--

$ nginx -v
nginx version: nginx/1.6.1

$ node -v
v0.10.30

--编辑2:nginxgzip配置--

# http://nginx.org/en/docs/http/ngx_http_gzip_module.html
gzip on;
gzip_buffers 32 4k;
gzip_comp_level 1;
gzip_min_length 1000;
#gzip_http_version 1.0;
gzip_types application/javascript text/css
gzip_proxied any;
gzip_vary on;
4

1 回答 1

2

你是对的,让我详细说明。

标头是需要发送的第一件事。但是,由于您使用的是流式压缩,因此最终大小是不确定的。您只知道未压缩资产的大小,发送太大的 Content-Length 也是不正确的。

因此,有两种选择:

  1. 传输编码分块
  2. 在发送任何数据之前完全压缩资产,因此压缩后的大小是已知的

目前,您正在经历第一种情况,听起来您确实需要第二种情况。获得第二种情况的最简单方法是打开 gzip_static 正如@kodeninja 在评论中所说的那样。

于 2016-03-03T10:18:18.570 回答