nginx服务页面取决于协议

时间:2016-05-09 19:35:34

标签: http nginx http2

我想同时针对HTTP / 2和HTTP / 1.x优化我的网站。对于HTTP / 2(和SPDY),由于没有额外的请求往返,我想分别提供我的CSS和JS文件,以获得独立缓存每个文件的好处。但是,如果我只这样做,HTTP / 1.x客户端将遭受额外的往返;所以对他们来说,我想连接我的CSS和JS文件。

理想情况下,HTTP / 2用户将获得此HTML:

<html>
  <head>
    <link rel="stylesheet" href="stylesheet-1.css">
    <link rel="stylesheet" href="stylesheet-2.css">
  </head>
  <body>
    <script src="script-1.js"></script>
    <script src="script-2.js"></script>
  </body>
</html>

HTTP / 1.x用户将获得此HTML:

<html>
  <head>
    <link rel="stylesheet" href="all-stylesheets.css">
  </head>
  <body>
    <script src="all-scripts.js"></script>
  </body>
</html>

是否可以根据客户端的协议配置nginx以提供不同的HTML文件?

1 个答案:

答案 0 :(得分:2)

是的,您可以通过$server_protocol变量执行此操作。我通常建议通过变量扩展来插入文件位置。但在这种情况下,我担心这会让你对注入攻击开放,因为这个变量的内容似乎是从请求行逐字复制的。

但是,有一个解决方案是利用ngx_http_map_module。假设您的网站位于/srv/www

map $server_protocol $version {
    default       "1.1";
    "HTTP/2.0"    "2.0";
    # extra case for any SPDY version
    "~SPDY/"      "2.0";
}

server {
    listen            [::]:80;
    # The line below requires a working SSL configuration!
    listen            [::]:443 ssl http2;
    server_name       example.com
    root              /srv/www/http-1.1/htdocs;

    location / {
        root          /srv/www/http-$version/htdocs;
        try_files     $uri $uri/ @fallback;
    }

    # fallback for HTTP/1.1 files. If this fails as well, we get a 404.
    location @fallback {
        try_files     $uri $uri/ =404;
    }
}

这将针对HTTP / 2.0请求提供/srv/www/http-2.0/htdocs以外的所有请求,并针对所有其他请求提供/srv/www/http-1.1/htdocs以外的所有请求。如果找不到专门为HTTP / 2.0设计的资源,则HTTP / 1.1的相应文件将作为后备服务。