如何在nginx中仅有时添加头信息

19

我有一个 Nginx 反向代理到 API 服务器。API 有时会设置缓存控制头。如果 API 没有设置缓存控制,我希望 Nginx 覆盖它。

我该怎么做?

我认为我想做类似于这样的事情,但它不起作用。

location /api {
  if ($sent_http_cache_control !~* "max-age=90") {
    add_header Cache-Control no-store;
    add_header Cache-Control no-cache;
    add_header Cache-Control private;
  }
  proxy_pass $apiPath;
}

你能否澄清一下,您是想在上游没有设置头部或者头部不包含 max-age=90 的情况下覆盖它吗? - Ivan Tsirulev
谢谢@IvanTsirulev。理想情况下,如果它不存在就好了。但是在那个例子中,我试图匹配上游设置的值。 - Stephen
2个回答

20

由于if是重写模块的一部分,在请求处理的早期阶段就被评估了,远在调用proxy_pass并从上游服务器返回头之前。因此您无法在此处使用if

解决您的问题的一种方法是使用map指令。使用map定义的变量仅在使用时才会被计算,这正是您在此处所需的。简单来说,在这种情况下,您的配置将如下所示:

# When the $custom_cache_control variable is being addressed
# look up the value of the Cache-Control header held in
# the $upstream_http_cache_control variable
map $upstream_http_cache_control $custom_cache_control {

    # Set the $custom_cache_control variable with the original
    # response header from the upstream server if it consists
    # of at least one character (. is a regular expression)
    "~."          $upstream_http_cache_control;

    # Otherwise set it with this value
    default       "no-store, no-cache, private";
}

server {
    ...
    location /api {
        proxy_pass $apiPath;

        # Prevent sending the original response header to the client
        # in order to avoid unnecessary duplication
        proxy_hide_header Cache-Control;

        # Evaluate and send the right header
        add_header Cache-Control $custom_cache_control;
    }
    ...
}

参见:https://dev59.com/5GYr5IYBdhLWcg3wkK2w#44761645 - aksh1618

10

Ivan Tsirulev的回答是正确的,但您不必使用正则表达式。

Nginx会自动将map的第一个参数用作默认值,因此您也不必添加它。

# Get value from Http-Cache-Control header but override it when it's empty
map $upstream_http_cache_control $custom_cache_control {
    '' "no-store, no-cache, private";
}

server {
    ...
    location /api {
        # Use the value from map
        add_header Cache-Control $custom_cache_control;
    }
    ...
}

NGINX文档表示,如果未指定default,则该值将为一个空字符串。http://nginx.org/en/docs/http/ngx_http_map_module.html - Eric Ihli

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