缓存控制永久 301 重定向 nginx

缓存控制永久 301 重定向 nginx

我想知道是否有办法控制 Nginx 中重定向的生命周期?

我们希望在 CDN 中缓存 301 重定向特定时间,比如说 20 分钟,并且 CDN 由标准缓存标头控制。默认情况下,Nginx 重定向没有 Cache-control 或 Expires 指令。这可能会导致重定向被缓存很长时间。通过设置特定的重定向生命周期,系统可以有机会自我纠正,因为即使“永久”重定向也会不时发生变化。

另一件事是这些重定向包含在服务器块中,根据 nginx 规范,应该在位置之前进行评估。

我尝试将 add_header Cache-Control "max-age=1200, public"; 添加到重定向文件的底部,但问题是 Cache-control 被添加了两次 - 第一次来自后端脚本,另一次由 add_header 指令添加。

在 Apache 中,有一个环境变量技巧可以控制重写的标头:

RewriteRule /taxonomy/term/(\d+)/feed /taxonomy/term/$1 [R=301,E=expire:1] Header 始终设置 Cache-Control “store, max-age=1200” env=expire

但我不确定如何在 Nginx 中实现这一点。

答案1

我也使用“环境变量技巧”在 Apache 中执行此操作,并正在寻找 nginx 中的等效方法。自从第一次提出这个问题以来已经过去了几年,所以从那时起事情可能已经发生了变化,但我确实找到了一种在 nginx 1.14 中设置重定向默认生存期的方法。

server块中,您可以使用映射变量根据返回状态代码 ( )设置指令的值,从而有效地为所有 301 重定向设置新的默认值Cache-Control和标头值。如果需要,可以在必要时在更具体的块中覆盖此新默认值。作为额外的好处,您不必像在 Apache 中那样在每次重定向时重复指定环境变量。Expiresexpires$statuslocation

以下示例说明了这一点,其中所有 HTTP 请求都使用仅持续一小时的“永久”301 重定向升级到 HTTPS。对于以 为前缀的 URI 有一个例外/override,其中 301 确实是永久的。

map $status $expires {
        default off;
        301     1h;
}

server {
        listen 80 default_server;
        server_name _;
        expires $expires;
        location /override {
                return 301 https://$host/somewhere;
                expires off;
        }
        location / {
                return 301 https://$host$request_uri;
        }
}

这给出了预期的标题值:

$ curl -I http://localhost
HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.0 (Ubuntu)
Date: Thu, 11 Jun 2020 01:01:43 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://localhost/
Expires: Thu, 11 Jun 2020 02:01:43 GMT
Cache-Control: max-age=3600

$ curl -I http://localhost/override
HTTP/1.1 301 Moved Permanently
Server: nginx/1.14.0 (Ubuntu)
Date: Thu, 11 Jun 2020 01:01:49 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://localhost/somewhere

答案2

您是否尝试过在 nginx 配置中使用 Cache-Control 标志?

示例配置:

upstream yourappserver{
  server 0.0.0.0:6677;
}


proxy_cache_path  /tmp/cache levels=1:2 keys_zone=my-test-cache:8m max_size=5000m inactive=300m;

server {
    listen 80;
    server_name your.domain.tld;
    root /path/to/the/document/root/;

    access_log  /var/log/nginx/access.log;

    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_cache my-test-cache;
      proxy_cache_valid  200 404  1m;
      proxy_cache_valid 302 20m;

      proxy_cache_use_stale   error timeout invalid_header updating;
      proxy_redirect off;

      if (-f $request_filename/index.html) {
        rewrite (.*) $1/index.html break;
      }
      if (-f $request_filename.html) {
        rewrite (.*) $1.html break;
      }
      if (!-f $request_filename) {
        proxy_pass http://yourappserver;
        break;
      }
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
      root html;
    }
}

我认为您正在寻找这个特定的配置片段

proxy_cache_valid 302 20m;

相关内容