Nginx HTTP/2 Server Push

Nginx 在最新的 1.13.9 版本中,增加了对 HTTP/2 Server Push 的支持,以下就简单介绍下如何使用。

以下内容主要来自 Introducing HTTP/2 Server Push with NGINX 1.13.9,进行了简单的整理。

推送指定资源

首先,在 Nginx 中进行配置:

server {
    #开启HTTP/2
    listen 443 ssl http2;

    ssl_certificate ssl/certificate.pem;
    ssl_certificate_key ssl/key.pem;

    root /var/www/html;

    # 当请求 demo.html 时,推送 /style.css, /image1.jpg, /image2.jpg
    location = /demo.html {
        http2_push /style.css;
        http2_push /image1.jpg;
        http2_push /image2.jpg;
    }
}

可以通过 Chrome Developer Tools 查看效果。在 Network 中,可以看到 demo.html 的请求和推送到客户端的内容。

如下图所示,可以看到 style.css,image1.jpg,image2.jpg。它们都是 demo.html 请求的一部分。

自动推送

以上是在页面加载时推送指定资源的例子,但是很多情况下,并不能指定要推送哪些资源,因此,Nginx 还支持通过 http2_push_preload 指令,自动分析响应头中的 Link header,来自动推送这些资源。

server {
    #开启HTTP/2
    listen 443 ssl http2;

    ssl_certificate ssl/certificate.pem;
    ssl_certificate_key ssl/key.pem;

    root /var/www/html;

    location = /myapp {
        proxy_pass http://upstream;
        http2_push_preload on;
    }
}

通过如上的配置,当 upstream 返回的响应头中包含 Link header 时,

Link: </style.css>; as=style; rel=preload

Nginx 即会开启一个推送, 内容则是 /style.css ,Link header 的路径必须是绝对路径。

如果想要推送多个资源,可以添加多个 Link header , 或更直接一些,把所有资源添加到一个 Link header 中。

Link: </style.css>; as=style; rel=preload, </favicon.ico>; as=image; rel=preload

如果不想让 Nginx 推送某个资源,为该 header 添加一个 nopush 参数即可。

Link: </nginx.png>; as=image; rel=preload; nopush

有选择的推送

由于 HTTP/2 规范并没有解决是否要推送哪些资源的问题,但是比较合理的方式是知道需要推送哪些资源,并且客户端没有缓存过这些资源,才进行推送。

所以 Nginx 支持了添加条件,只在符合条件时才进行推送

当客户端请求时包含了 cookie ,Nginx 将只会推送一次资源。

server {
    listen 443 ssl http2 default_server;

    ssl_certificate ssl/certificate.pem;
    ssl_certificate_key ssl/key.pem;


    root /var/www/html;
    http2_push_preload on;

    location = /demo.html {
        add_header Set-Cookie "session=1";
        add_header Link $resources;
    }
}


map $http_cookie $resources {
    "~*session=1" "";
    default "</style.css>; as=style; rel=preload, </image1.jpg>; as=image; rel=preload,
             </image2.jpg>; as=style; rel=preload";
}

相关链接:

在Go中使用 HTTP/2 Server Push

参考资料:

Server Push (HTTP/2)