我们有一个使用Node/express构建的Web应用程序,除了正常内容外,还提供静态资源服务,通过express.static()实现。在它前面有一个nginx服务器,如果用户代理支持,它当前配置为gzip这些静态资源请求。
但是,尽管nginx按预期进行了gzip处理,但它从原始响应中删除Content-Length标头,并设置Transfer-Encoding: chunked。这会破坏我们CDN上的缓存。
以下是来自Node后端和nginx的典型静态资源请求(JS文件)的响应: 请求:
--编辑1:版本信息--
但是,尽管nginx按预期进行了gzip处理,但它从原始响应中删除Content-Length标头,并设置Transfer-Encoding: chunked。这会破坏我们CDN上的缓存。
以下是来自Node后端和nginx的典型静态资源请求(JS文件)的响应: 请求:
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
我们当前的静态资源 location
的 nginx
配置如下:
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;
}
从上面的配置可以看出,尽管按照nginx文档的要求对这些路径显式设置了 chunked_transfer_encoding
为 off
,并且启用了 proxy_buffering
和足够大的 proxy_buffers
大小,但响应仍然是分块传输的。我们错过了什么吗?--编辑1:版本信息--
$ nginx -v
nginx version: nginx/1.6.1
$ node -v
v0.10.30
--编辑2:nginx
gzip配置--
# 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;
gzip
配置。你说得对,资产正在动态压缩。我还看到了gzip_static
模块,可以帮助实现你所描述的功能。因此,在我们的情况下,我们要么必须在nginx
上托管原始+gzipped资产,配置gzip_static
,然后它会做正确的事情。或者,在我们的资产构建阶段中预先构建它们,在Node
上构建一些智能,以根据当前请求提供其中之一,并关闭nginx
上的gzip
。 - kodeninja