如何在 nginx 中为某些文件扩展名添加带有代理传递的缓存控制标头

law*_*tog 4 nginx cache-control nginx-reverse-proxy nginx-config

我喜欢使用 nginx 添加缓存控制标头来获取某些扩展名,例如 .jpg 等,但到目前为止我在网上找到的一些解决方案,我无法让它工作。我会告诉你我尝试过什么。

我在站点的 .conf 文件中的不同位置尝试了以下变体,当我尝试时,站点变成空白,并且在控制台上发现了很多 404 错误。该网站是用 React 开发的。

location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
    expires 1d;
    add_header Cache-Control "public, no-transform";
}
Run Code Online (Sandbox Code Playgroud)

我的conf 文件如下所示。问题是我必须进行反向代理,因为这些站点实际上托管在 Docker 容器中。

 server {
    server_name mysite.net;
    root         /usr/share/nginx/html;

    location / {
        proxy_pass http://web:3005/;
    }

    location /api/ {
        rewrite ^/api(/.*)$ $1 break;

        proxy_pass  http://api:5005/;
        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_set_header X-Forwarded-Proto https;
        proxy_redirect    off;
        fastcgi_read_timeout 1200;
        proxy_read_timeout 1200;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mysite.net-0001/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mysite.net-0001/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = mysite.net) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name mysite.net;
    return 404; # managed by Certbot
}
Run Code Online (Sandbox Code Playgroud)

Iva*_*sky 8

使用map指令:

map $cache $control {
    1       "public, no-transform";
}

map $cache $expires {
    1       1d;
    default off; # or some other default value
}

map $uri $cache {
    ~*\.(js|css|png|jpe?g|gif|ico)$    1;
}

server {
    ...
    expires $expires;
    add_header Cache-Control $control;
    ...
}
Run Code Online (Sandbox Code Playgroud)

(您还可以将expiresadd_header指令放入location上下文中,甚至将 then 留在http上下文中)。$control如果通过变量的映射表达式计算的值是空字符串,nginx 根本不会添加标头(或修改现有标头) 。这不是唯一可能的解决方案,您还可以依赖Content-Type来自上游的响应标头(请参阅答案以获取示例)。

您应该了解文档摘录:

可能有多个add_header指令。当且仅当当前级别上没有add_header定义任何指令时,这些指令才会从先前的配置级别继承。