Nginx如何对应到磁盘文件上,看似简单(好像无非就是由URL映射到磁盘文件),但实际上还是有可值得琢磨的地方,记录一下。

主要是几个指令:

  • root
  • alias
  • try_files

root

最主要的当然是root,规定了项目的【根目录】所有的URL都以此为起始路径去寻找文件,如:

server{
        server_name whj.site
        root /home/wuhuaji/;
        index index.html;
}

那么当访问 http://whj.site/a/b/test.html的时候,就会对应到 /home/wuhuaji/a/b/test.html 这个文件;

但是root指令有个缺点,无论URL时什么样,都以指令的值作为起点,再去匹配URL中的路径,如:

    location ^~ /test/ {
        root /home/test/;
        index index.html;
    }

在这里,如果设定一个规则,希望访问的URL如果是 /test/开头的话,就对应到文件中的 /home/test,比方说,访问http://whj.site/test/index.html ,希望对应到 /home/test/index.html。但是如前所述,这里实际上匹配到的是:/home/test/test/index.html

显然不满足最初的设想。这时候就需要用到alias指令了。

alias

所谓alias指令,就是解决上述root指令的问题:

    location ^~ /test/ {
        alias /home/test/;
        index index.html;
    }

如果用alias来指定,那么访问http://whj.site/test/index.html ,就对应到了/home/test/index.html,这样就更加直观了。

try_files:

还有一个指令try_files, 经常在各种Nginx配置中看到,一直不以为意,却大有用处。
指令大概是这样:try_files path1 path2 default_path,理解起来也简单:先尝试去找path1,如果找不到就是找path2……一直找下去,通常还会设一个默认路径,以免不能匹配就尴尬了。
具体来说:

location /test/ {
    try_files $uri $uri/ /default.html;
}

这里,如果访问:http://whj.site/test/a 那首先就尝试去找 /home/wuhuaji/test/a 看看是否有这个文件,如果没有就看/home/wuhuaji/test/a/index.html,如果再没有,就找 /home/wuhuaji/default.html。

try_files的妙用:

在很多Nginx配置中,都看到有类似这样的用法:

        location / {
           try_files $uri $uri/ /index.php?$query_string;
        }
        location ~ [^/]\.php(/|$) {
           try_files $uri =404;
            fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
            fastcgi_index index.php;
            include /etc/nginx/fastcgi_params;
        }

也就是,首先通过location / 将所有URL匹配到,然后去找文件,找不到就交给 index.php 来处理。也就是所谓的单入口的模式,把所有请求都给到一个统一入口,由这个入口去分发具体的请求。看了一些Nginx配置,几乎都是这样的模式,也就是将URL重写这一步,从Nginx转移到后端语言中。至于为什么单入口比较好,不在这里的讨论范围,有时间再总结下。