zad*_*ops 23 if-statement nginx and-operator
我正在尝试根据响应标头缓存请求。现在我想要的条件是如果响应同时具有 2 个标头 client-device 和 client-location,那么响应应该缓存在 nginx 端
所以我尝试使用这段代码
if ($http_client_device && $http_clocation) {
set $cache_key "$request_uri$http_client_device$http_client_location";
}
proxy_cache_key $cache_key;
Run Code Online (Sandbox Code Playgroud)
但 nginx 不允许 nginx: [emerg] 意外的“&&”条件...
无论如何要解决这个问题吗?提前致谢
zad*_*ops 26
经过一整天的搜索后,我找到了一种解决方法,参考此主题 http://rosslawley.co.uk/archive/old/2010/01/04/nginx-how-to-multiple-if-statements/
所以一般来说我的代码将如下所示:
if ($http_client_device) {
set $temp_cache 1;
}
if ($http_client_location) {
set $temp_cache 1$temp_cache;
}
if ($temp_cache = 11) {
set $cache_key ...;
}
Run Code Online (Sandbox Code Playgroud)
但仍然想知道是否有更干净的方法在 nginx 中执行 AND 运算符
Ste*_*ing 20
if尽量少用。
请注意,Nginx 在匹配时更改上下文块if(更多详细信息)
为了避免if更改上下文块,使用map更好
# if ($arg_a == "" && $arg_b == "")
http {
# map need in http context
map "$arg_a$arg_b" $is_empty {
default 0;
"" 1;
}
server {
if ($is_empty) {
# ...
}
# ...
}
}
Run Code Online (Sandbox Code Playgroud)
检查多个匹配
# if ($arg_a == "apple" && $arg_b == "boy")
http {
# map need in http context
map $arg_a $match_a {
default 0;
apple 1;
}
map $arg_b $match_b {
default 0;
boy 1;
}
map "$match_a$match_b" $match {
default 0;
11 1;
}
server {
if ($match) {
# ...
}
# ...
}
}
Run Code Online (Sandbox Code Playgroud)
如果您确认您的配置有效,甚至if可以更改上下文块。
set $and 1;
if (<not condition>) {
set $and 0;
}
if (<not condition>) {
set $and 0;
}
if ($and) {
# ...
}
Run Code Online (Sandbox Code Playgroud)
例如:
if ($arg_a = 1 && $arg_b = 2) { ... }
Run Code Online (Sandbox Code Playgroud)
可以实现
set $ab 1
if ($arg_a != 1) {
set $ab 0;
}
if ($arg_b != 2) {
set $ab 0;
}
if ($ab) {
# ...
}
Run Code Online (Sandbox Code Playgroud)
参考:Nginx
if,and
对于您的情况
set $set_cache_key 1;
if ($http_client_device = "") {
set $set_cache_key 0;
}
if ($http_clocation = "") {
set $set_cache_key 0;
}
if ($set_cache_key) {
set $cache_key "$request_uri$http_client_device$http_client_location";
}
proxy_cache_key $cache_key;
Run Code Online (Sandbox Code Playgroud)