意外混合了 http2 和 1.1 响应

意外混合了 http2 和 1.1 响应

我正在将 nginx 配置为反向代理(在某些 http/1.1 服务器前面)。我最初在 nginx 实例上设置了一个原始服务器。正如预期的那样,它仅通过 HTTP/2 返回内容。但是,当我将 nginx 配置为提供代理服务时,它返回了 HTTP2 和 HTTP/1.1 响应的混合。

 server {
    listen 443 ssl http2;
    server_name www.example.com;

    ssl_certificate /etc/nginx/ssl/example.com/cert.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com/cert.key;
    include snippets/ssldefaults.conf;

    location / {
         proxy_http_version      1.1;
         proxy_set_header        Host $host;
         proxy_set_header        X-Real-IP $remote_addr;
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

         proxy_ssl_verify off;
         proxy_pass  https://192.168.23.12/
    }
 }

(我使用 Chrome 76.0.3809.132 和 nginx 1.14 来测试)

nginx 中显示的不同协议均来自同一源服务器。我的测试用例(例如)包含多个可缓存的 CSS 文件 - 一些通过 HTTP2 到达,一些通过 1.1 到达。

什么原因造成这种差异?

答案1

无法通过同一连接提供 HTTP/2 和 HTTP/1.1 服务。

因此,我建议可以采取以下措施之一:

  1. 您正在通过不同的域请求资源,但它们并非全部都通过您的 nginx 服务器。
  2. 您正在查看第三方请求(例如 Google Analytics),而不是您网站的请求。
  3. 您正在查看缓存资源,它们最初是通过 HTTP/1.1 下载的。
  4. 您正在使用 ServiceWorker 并且Chrome 无法正确报告它们的协议
  5. 您在 Chrome 中发现了一个错误!

我建议您添加$server_protocol到您的 nginx,log_format以便您可以在服务器端跟踪请求实际使用的协议:

log_format my_log_format '$remote_addr - $remote_user [$time_local] '
      '$server_protocol "$request" $status $body_bytes_sent '
      '"$http_referer" "$http_user_agent"';
access_log /usr/local/nginx/nginx-access.log my_log_format;

相关内容