简单来说就是有了 server push,服务器也有能力主动给客户端推送内容了。
传统的网页请求方式和有 server push 的请求方式对比
配置 server push
1.首先,我们看下未启用 server push 之前的请求,当请求网站根目录下的 /index.html 服务器会加载资源,如果 A 资源依赖 B, 则在去请求 B
2.开启 server push 需要 nginx 1.13.9 以上版本,在 server 段配置如下
要将资源与页面加载一起推送,请http2_push按如下所示使用该指令:
listen 443 ssl http2; # 需要开启 http2
……
location / {
http2_push /uploads/IMG_4224.JPG;
http2_push /images/netease.png;
}
验证HTTP / 2服务器推送
1.然后再次请求可以看到请求中会有 push 的字段,服务器开始先请求 /index.html 如果配置了 server push 则会直接把对应的资源一并返回给客户端。
2.也可以用 nghttp 测试,带*的表示是支持 server push 的
➜ ~ nghttp -ans https://awen.me
***** Statistics *****
Request timing:
responseEnd: the time when last byte of response was received
relative to connectEnd
requestStart: the time just before first byte of request was sent
relative to connectEnd. If '*' is shown, this was
pushed by server.
process: responseEnd - requestStart
code: HTTP status code
size: number of bytes received as response body without
inflation.
URI: request URI
see http://www.w3.org/TR/resource-timing/#processing-model
sorted by 'complete'
id responseEnd requestStart process code size request path
13 +31.14ms +164us 30.97ms 200 9K /
15 +88.43ms +31.20ms 57.23ms 200 11K /css/main.css?v=5.1.1
21 +88.50ms +31.23ms 57.27ms 200 1K /js/src/utils.js?v=5.1.1
23 +88.66ms +31.23ms 57.43ms 200 1K /js/src/motion.js?v=5.1.1
25 +88.70ms +31.23ms 57.47ms 200 1017 /js/src/affix.js?v=5.1.1
27 +88.71ms +31.23ms 57.48ms 200 274 /js/src/schemes/pisces.js?v=5.1.1
29 +89.84ms +31.23ms 58.61ms 200 1K /js/src/scrollspy.js?v=5.1.1
31 +89.89ms +31.24ms 58.65ms 200 940 /js/src/post-details.js?v=5.1.1
33 +89.90ms +31.24ms 58.66ms 200 859 /js/src/bootstrap.js?v=5.1.1
17 +91.21ms +31.22ms 59.99ms 200 4K /favicon.ico?v=5.1.1
19 +114.58ms +31.23ms 83.35ms 200 26K /uploads/IMG_4224.JPG
10 +224.05ms * +24.51ms 199.54ms 200 4K /favicon.ico
12 +224.12ms * +24.52ms 199.60ms 404 162 /IMG_4224.JPG
14 +224.22ms * +24.53ms 199.69ms 200 2K /images/netease.png
8 +313.28ms * +24.50ms 288.78ms 200 47K /sitemap.xml
2 +319.28ms * +23.30ms 295.98ms 200 119K /rss.xml
4 +431.86ms * +24.48ms 407.38ms 200 129K /baidusitemap.xml
6 +1.53s * +24.49ms 1.50s 200 1M /search.xml
自动将资源推送给客户
在很多情况下,列出您希望推送到NGINX配置文件中的资源是不方便的,甚至是不可能的。出于这个原因,NGINX也支持拦截Link预加载头的约定,然后推送这些头中标识的资源。要启用预加载,请http2_push_preload在配置中包含指令:
server {
# Ensure that HTTP/2 is enabled for the server
listen 443 ssl http2;
ssl_certificate ssl/certificate.pem;
ssl_certificate_key ssl/key.pem;
root /var/www/html;
# Intercept Link header and initiate requested Pushes
location = /myapp {
proxy_pass http://upstream;
http2_push_preload on;
}
}
例如,当NGINX作为代理服务器(用于HTTP,FastCGI或其他流量类型)运行时,上游服务器可以Link为其响应添加如下标题:
Link: </style.css>; as=style; rel=preload
NGINX拦截这个头并开始服务器推送/style.css。Link标题中的路径必须是绝对路径 - 不支持像./style.css这样的相对路径。该路径可以选择包含查询字符串。
要推送多个对象,可以提供多个Link标题,或者更好的是,将所有对象包含在逗号分隔的列表中:
Link: </style.css>; as=style; rel=preload, </favicon.ico>; as=image; rel=preload
如果您不希望NGINX推送预加载的资源,请将该nopush参数添加到标头中:
# Resource is not pushed
Link: </nginx.png>; as=image; rel=preload; nopush
当http2_push_preload启用时,您还可以通过在NGINX配置中设置响应标题来启动预加载服务器推送:
add_header Link "</style.css>; as=style; rel=preload";
有选择地向客户推送资源
HTTP / 2规范没有解决确定是否推送资源的挑战。显然,如果你知道他们可能需要这些资源并且不太可能已经缓存了资源,那么最好只将资源推送给客户端。
一种可能的方法是仅在首次访问该网站时将资源推送给客户。例如,您可以测试会话cookie的存在情况,并Link有条件地设置标题,以便仅在会话cookie不存在时才预加载资源。
假设客户端运行良好,并在随后的请求中包含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";
}