nginx正则相关变量$1,$2,$3使用注意

今天在配置nginx缓存图片时发现,一旦加上缓存配置,请求图片就会报错404。后发现在错误日志中图片的请求路径发生了奇怪的变化。

期望的请求地址:/user/apps/luwuer.com/img/xxx.jpg
实际请求地址却变作:/user/apps/jpg/luwuer.com/img/xxx.jpg

此时的nginx配置

server {
    listen       80 default_server;
    server_name  ~^(\w+\.)?(luwuer\.com)$; # $1 = 'blog.' || 'img.' || '' ; $2 = 'luwuer.com'

    root /root/apps/$1$2;

    location ~* \.(jpeg|png|gif|jpg)$ {
        expires 14d; # 缓存14天
        log_not_found on; # 是否在error.log中记录不存在的错误, 默认是
        access_log off; # 是否在access.log中记录
    }
    
    # ...
}

最终发现导致问题的原因,是root /root/apps/$1$2;,总结说来是两个原因。

  1. $1|$2|$3 ...是nginx在匹配正则时生成的变量,用于捕获一个正则表达式括号中匹配的字符串(从左到右依次存储在$1|$2|$3 ...中),新值覆盖旧值。
  2. location块中未设置root时,会取外层(server块)的root,但server.root明显不是先生成字符串然后赋值给location.root,而是直接把模板串交给location.root。

本配置中server.root被设置为/root/apps/$1$2/root/apps/luwuer.com$1 = '',$2 = 'luwuer.com'),在匹配到图片请求时$1被改变为图片的后缀名(/root/apps/jpg/luwuer.com# $1 = 'jpg',$2 = 'luwuer.com'),故访问地址错误找不到图片。

既然知道了原理,要修改也是简单,只需把第一次匹配到的$1,$2保存到自定义变量中。
修改后配置

server {
    listen       80 default_server;
    server_name  ~^(\w+\.)?(luwuer\.com)$; # $1 = 'blog.' || 'img.' || '' ; $2 = 'luwuer.com'
    
    set $pre $1;
    set $next $2;

    root /root/apps/$pre$next;

    location ~* \.(jpeg|png|gif|jpg)$ {
        expires 14d; # 缓存14天
        log_not_found on; # 是否在error.log中记录不存在的错误, 默认是
        access_log off; # 是否在access.log中记录
    }
    
    # ...
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容