NGINX浏览器缓存未生效-Node JS EC2

3

我看了几篇文章,但仍然无法弄清楚为什么浏览器缓存不起作用。我同时使用prerender.io和SSL:

gzip on;
gzip_min_length  500;
gzip_proxied     any;
gzip_comp_level 4;
gzip_types  text/css text/javascript text/xml text/plain text/x-component application/javascript application/json application/xml application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml;
gzip_vary on;
gzip_disable     "msie6";

server {
    listen 8080 default_server;
    listen [::]:8080 default_server;
    server_name <servername> www.<servername>.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2 default_server;
    server_name <servername> www.<servername>.com;

    ssl_certificate /etc/pki/tls/private/<servername>.com.chained.crt;
    ssl_certificate_key /etc/pki/tls/private/private.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers <ssl_ciphers_code>

    ssl_session_cache shared:SSL:5m;
    ssl_session_timeout 1h;
    add_header Strict-Transport-Security "max-age=15768000" always;

    root /var/app/current;

    location / {
        proxy_set_header X-Prerender-Token iKJwgCElYIfxtt9u99Zg;

        set $prerender 0;
        if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
            set $prerender 1;
        }
        if ($args ~ "_escaped_fragment_") {
            set $prerender 1;
        }
        if ($http_user_agent ~ "Prerender") {
            set $prerender 0;
        }
        if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
            set $prerender 0;
        }

        #resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
        resolver 8.8.8.8;

        if ($prerender = 1) {
            #setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
            set $prerender "service.prerender.io";
            rewrite .* /$scheme://$host$request_uri? break;
            proxy_pass http://$prerender;
        }

        # Proxy_pass configuration
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_max_temp_file_size 0;
        proxy_pass http://0.0.0.0:3000;
        proxy_redirect off;
        proxy_read_timeout 240s;
    }

    location ~* \.(ico|css|js|gif|jpeg|jpg|png|woff|ttf|otf|svg|woff2|eot)$ {
        root /var/app/current/app/dist/client/; #if i comment this out it, my css and js files are not found...
        expires 30d;
        access_log  off;
        log_not_found off;
        add_header  Pragma "public";
        add_header  Cache-Control "public";
    }

    # Increase http2 max sizes
    http2_max_field_size 64k;
    http2_max_header_size 64k;
    client_max_body_size 4G;
    keepalive_timeout 10;
}

我的资产目录如下:

JS:/var/app/current/app/dist/client/js

CSS:/var/app/current/app/dist/client/assets/css

图像:/var/app/current/app/dist/client/assets/graphics

字体:/var/app/current/app/dist/client/assets/fonts

视频:/var/app/current/app/dist/client/assets/videos

更新的配置:

gzip on;
gzip_min_length  500;
gzip_proxied     any;
gzip_comp_level 4;
gzip_types  text/css text/javascript text/xml text/plain text/x-component application/javascript application/json application/xml application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml;
gzip_vary on;
gzip_disable     "msie6";

server {
  listen 8080 default_server;
  listen [::]:8080 default_server;
  server_name <servername.com> <www.servername.com>;
  return 301 https://$server_name$request_uri;
}

server {
  listen 443 ssl http2 default_server;
  server_name <servername.com> <www.servername.com>;

  ssl_certificate /etc/pki/tls/private/<servername>.com.chained.crt;
  ssl_certificate_key /etc/pki/tls/private/private.key;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_ciphers <ciphers>;

  ssl_session_cache shared:SSL:5m;
  ssl_session_timeout 1h;
  add_header Strict-Transport-Security "max-age=15768000" always;

  root /var/app/current;

  location / {
      proxy_set_header X-Prerender-Token <token> ;

      set $prerender 0;
      if ($http_user_agent ~* "developers\.google\.com|googlebot|gigabot|yeti|yandex|ia_archiver|baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
          set $prerender 1;
      }
      if ($args ~ "_escaped_fragment_") {
          set $prerender 1;
      }
      if ($http_user_agent ~ "Prerender") {
          set $prerender 0;
      }
      if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
          set $prerender 0;
      }

      #resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
      resolver 8.8.8.8;

      if ($prerender = 1) {
          #setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
          set $prerender "service.prerender.io";
          rewrite .* /$scheme://$host$request_uri? break;
          proxy_pass http://$prerender;
      }

      # Proxy_pass configuration
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-NginX-Proxy true;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_max_temp_file_size 0;
      proxy_pass http://0.0.0.0:3000;
      proxy_redirect off;
      proxy_read_timeout 240s;
  }

  location ~* \.(ico|css|js|gif|jpeg|jpg|png|woff|ttf|otf|svg|woff2|eot)$ {
      root /var/app/current/app/dist/client/; #if i comment this out it, my css and js files are not found...
      expires 30d;
      access_log  off;
      log_not_found off;
      add_header  Pragma "public";
      add_header  Cache-Control "public";
  }

  location /assets/graphics/ {
    proxy_ignore_headers Cache-Control;
    proxy_cache_valid any 30d;
  }

  # Increase http2 max sizes
  proxy_buffers 8 16k;
  proxy_buffer_size 32k;
  http2_max_field_size 64k;
  http2_max_header_size 64k;
  client_max_body_size 4G;
  keepalive_timeout 10;
}

1
你能分享一下你的URL吗?如果我们能在调试器模式下运行浏览器来帮助确定问题,那么我们可能可以更好地帮助解决故障。 - Taterhead
1个回答

5
在您的NGINX配置中,您可以使用以下行将图像的缓存过期时间设置为30天:
expires 30d;

然而,查看来自您服务器的图像时,图像的最大年龄设置为0,这会导致您的浏览器在刷新时重新获取图像(下面的图像是在刷新后显示的):

enter image description here

我怀疑NGINX是作为您解决方案中的一个源服务器的代理。此源服务器在缓存控制标头中将max-age设置为0,而NGINX尊重该设置。
根据NGINX缓存指南
默认情况下,NGINX尊重来自原始服务器的Cache-Control标头。它不会缓存具有设置为Private、No-Cache或No-Store的Cache-Control或者响应标头中带有Set-Cookie的响应。NGINX仅缓存GET和HEAD客户端请求。
要覆盖在源服务器上设置的cache-control并将max-age设置为30天,请使用NGINX proxy_ignore_headers和proxy_cache_valid指令,如下:
...
location /assets/graphics/ {

    proxy_ignore_headers Cache-Control;
    proxy_cache_valid any 30d;
    ...
}
...

我的解决方案中的代码直接取自NGINX缓存指南,并根据您的配置进行修改。
或者确定如何在源服务器上更改缓存控制标头。 更新 在您更新NGINX配置后,位于/assets/graphics/目录中的图像将从本地浏览器内存中获取,并具有30天(2595200)的过期时间,如下所示。昨天,它们都是从您的服务器获取而不被缓存。此解决方案解决了您的问题。对于其他要缓存的资产,您需要进一步更改配置以按照您的要求进行缓存。

enter image description here

enter image description here


我已经将您的建议添加到我的配置中,我测试了头文件,现在缓存控制设置为public。但问题仍然存在。Google无法检测缓存控制。我已更新我的问题并附上新的配置。https://developers.google.com/speed/pagespeed/insights/?url=http%3A%2F%2Ftroolr.com%2F - Shivam
1
问题已经不存在了。请查看我的更新答案,其中包含今天早上从您的网站截取的屏幕截图。我刚刚检查了一下,这些图片现在是从内存中获取的,并且具有30天的缓存过期时间(正如我们在解决方案中指定的那样)。我的解决方案解决了/assets/graphics/路径的缓存问题。如果Google看到其他需要相同处理的路径,您需要将相同的解决方案添加到这些路径中。 - Taterhead

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接