最近遇到了一个nginx配置难题
一个路由使用的不是root配置的根目录,然后还需要跳转,一下卡了一个月,幸亏不着急,昨天总算解决了

server {

listen 443 ssl;
server_name example.com;
root /www/current/public;

...

location ^~ /nginx/test/ {
    alias /home/test/nginxtest/;
    try_files $uri $uri/ /nginx/test/index.html;
    }

...

问题出在alias上,下面的location里使用root的话会在访问example.com/nginx/test会去找/home/test/nginxtest/nginx/test/index.html,相当于把路由插到路径里面了,使用alias就会直接找/home/test/nginxtest/index.html。需求是在访问example.com/nginx/test/{任意字符串}rewrite到example.com/nginx/test/index.html,而使用alias不支持rewrite,问题就出在这,虽然有很多解决办法,如后端改写路由等,但都不够完美。
nginx上一种解决办法是在前面插入一个location,rewrite到这个

location /nginx/test {

rewrite /nginx/test(.*) /test/index.html last;

}

location /test/ {

alias /home/test/nginxtest/;

index index.html;

}

但是这有个问题就是原来目录下的其他文件不能载入,如.js,.css,图片等,虽然可以使用if来解决但是都太麻烦

后来想到了try_files这个配置

一开始配置try_files $uri $uri/ /index.html
发现还是404,查看log发现找的文件是/www/current/public/index.html,去找根目录的index.html
这时隐隐感觉可以在index.html前插入路由/nginx/test/可以,因为之前在哪看到过nginx是会先找路径然后找路由,都没有才会返回404.
修改之后成功。访问example.com/nginx/test/{任意字符串},浏览器显示的还是example.com/nginx/test/{任意字符串},但是上找到文件是/home/test/nginxtest/下的index.html和js等文件。

以上方法只适用于一级路由,多级路由不行

更新配置

location ~ \.(js|jpg|jpeg|png|bmp|swf|css|ico)$ {
    rewrite (.*)/((.*)\.(js|jpg|jpeg|png|bmp|swf|css|ico))$ /$2 break;
}

location /api/v1 {
   proxy_pass https://eexample.com/api/v1
}

location / {
    try_files $uri $uri/ /index.html;
}

说明:
第一个location捕获js,css等静态文件
第二个location捕获api后台接口
第三个location捕获index.html

alias不能用于if和location @{字符串}字段

ps:如果报500错误,log里出现rewrite or internal redirection cycle,是因为找不到index.html文件