Nginx映射不使用我的正则表达式的参数

Ali*_*ash 3 nginx

我正在尝试使用nginx的地图,但结果并不是我所期望的.

这就是我所拥有的:

map $uri $new {
  default                                 "";
  ~*/cc/(?P<suffix>.*)$                   test.php?suffix=$suffix;
}

location ~     [a-zA-Z0-9/_]+$ {
        proxy_pass http://www.domain.com:81/$new;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Run Code Online (Sandbox Code Playgroud)

当我访问www.domain.com/cc/abc时,我会在日志中看到这一点

2012/03/29 17:27:53 [warn] 3382#0: *33 an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/5/00/0000000005 while reading upstream, client: 1.2.3.4, server: www.domain.com, request: "GET /cc/abc HTTP/1.1", upstream: "http://1270.0.0.1:81/test.php?suffix=$suffix", host: "www.domain.com"
Run Code Online (Sandbox Code Playgroud)

$ suffix不会被替换.

但是当我这样做时:

map $uri $new {
  default                                 "";
  ~*/cc/(?P<suffix>.*)$                   $suffix;
}

location ~     [a-zA-Z0-9/_]+$ {
        proxy_pass http://www.domain.com:81/$new;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Run Code Online (Sandbox Code Playgroud)

现在,当我去www.domain.com/cc/abc时,日志显示给我:

2012/03/29 17:29:39 [warn] 5916#0: *26 an upstream response is buffered to a temporary file /var/cache/nginx/proxy_temp/2/00/0000000002 while reading upstream, client: 1.2.3.4, server: www.domain.com, request: "GET /cc/abc HTTP/1.1", upstream: "http://1270.0.01:81/abc", host: "www.domain.com"
Run Code Online (Sandbox Code Playgroud)

因此,当重写包含包含变量的字符串时,它不会被替换.但如果它只包含变量,它将起作用.

我究竟做错了什么?

kol*_*ack 8

正如您所发现的,地图替换只能是静态字符串或单个变量.由于test.php?suffix = $ suffix不以$开头,因此nginx假设它只是一个静态字符串.您不需要使用地图,而是需要使用两次重写来完成您想要的任务:

location ~ [a-zA-Z0-9/_]+$ {
  rewrite ^/cc/(.*) /test.php?suffix=$1 break;
  rewrite ^ / break;

  proxy_pass http://www.domain.com:81;
  proxy_set_header X-Real-IP  $remote_addr;
  proxy_set_header Host $host;
  proxy_set_header X-Host $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Run Code Online (Sandbox Code Playgroud)

第一次重写将从网址中删除任何初始/ cc /并将其余内容作为地图尝试的网址arg附加.break标志告诉nginx停止处理重写指令.如果第一次重写不匹配,则第二次重写将始终匹配,并将url设置为/.

编辑:从1.11.0开始,地图值可以是复数值,因此原始配置将起作用