/usr/share/nginx/html 目录下有个一 index.html 文件。

1、常规需求

配置 http://www.abc.com/html/xxx 的请求全部在/usr/share/nginx/html目录下寻找资源

server {
    listen 80;
    server_name www.abc.com;
    location /html {
        root /usr/share/nginx;
    }
}

这时访问:

http://www.abc.com/html/index.html

http://www.abc.com/html/

http://www.abc.com/html

三者都能获取到 index.html 资源

2、奇怪的需求

配置 http://www.abc.com/odd/xxx 的请求全部在/usr/share/nginx/html目录下寻找资源。

(去掉/odd后剩余路径作为文件路径去匹配)

去掉路径中的一截儿,显然可以用rewrite 指令处理。

server {
    listen 80;
    server_name www.abc.com;
    location /odd {
        rewrite ^/odd(.*)$ $1 bread;
        root /usr/share/nginx/html;
    }
}

这时访问:

http://www.abc.com/odd/index.html 页面正常返回

http://www.abc.com/odd/ 404 Not Found

http://www.abc.com/odd 500 Internal Server Error

由此可见rewrite正则替换时

  • 替换项($1)为空会导致服务异常(500)。
  • 替换后的 / 则不在具备自动匹配欢迎页(index.html)的功能。用 / 在 /usr/share/nginx/html 文件夹中寻找,没有资源匹配就404了。

如何解决:

server {
    listen 80;
    server_name www.abc.com;
    location /odd {
        rewrite ^/odd/?$ /odd/index.html last;
        rewrite ^/odd(.*) $1 break;
        root /usr/share/nginx/html;
    }   
}

last 关键字通常用于执行重写后,将新的 URI 传递到下一个处理阶段,允许在一个新的 location 中重新匹配 URI。

break 通常用于在当前 location 块内结束重写操作,不再进行进一步的重写规则。

当然也可以通过多配几个 location 或者使用反向代理解决。

再看一种写法

server {
    listen 80;
    server_name www.abc.com;
    location /odd {
        rewrite ^/odd(.*) $1 break;
        root /usr/share/nginx/html;
    }   
    
    location / {
        root /usr/share/nginx/html;
    }
}

这时访问:

http://www.abc.com/odd/index.html 页面正常返回

http://www.abc.com/odd/ 页面正常返回

http://www.abc.com/odd 500 Internal Server Error

这样发现/odd/ 正常了,说明/odd/ 替换为/ 已经完成。之后在/usr/share/nginx/html没有找到可用资源,location /odd 这个location就匹配失败了。而后再去匹配优先级location /模块匹配,而后由于自动匹配到了欢迎页(index.html)。