Nginx – alias与root的区别
root
nginx会在硬盘中查找:root指定路径+ 访问的uri
。
这里提一个遇到的坑,就是root和index顺序问题,当root在location外边被所有location使用时,index一定要放在root后面,如果放前面,则nginx会去找nginx安装时的那个index而不是root里的index,但如果root放在location内部,外边的index虽然在root前面,但是却不会导致这个问题。
以下是一个vue dist的nginx配置(root放在index之前)
server {
listen 80;
server_name www.vue-element-admin.com;
charset utf-8;
default_type text/html;
root /Users/bruce/www/personal/vue-element-admin/dist;
index index.html index.htm index.php
access_log /usr/local/var/log/nginx/www.vue-element-admin.com.access.log;
error_log /usr/local/var/log/nginx/www.vue-element-admin.com.error.log;
location / {
try_files $uri $uri/ index.html$is_args$args;
}
location ~ .*\.(jpg|jpeg|png|gif)$ {
valid_referers none blocked www.vue-element-admin.com;
if ($invalid_referer) {
return "502" "Invalid Referer";
}
}
}
alias
- 当无修饰符或使用
^~
修饰location匹配的uri时,nginx会在硬盘中查找:alias指定路径+访问的uri中location匹配的部分之后的路径(不包括开头的斜杠/)
- 当使用
~
或~*
修饰时,它不会查找任何文件,而会查找它本身指定的目录(即这样的配置是不行的,除非你要显示目录中的文件)。
关于uri的说明
假设我访问:http://www.test.com/static/html/index.html?aa=bb,则访问的uri为:/static/html/index.html,即除去协议(http://或https://)及域名www.test.com之外的部分即为uri(注意不包括参数)
实例测试
注意,要保证access_log、error_log、root或alias指定的目录要存在并且有可读权限。
server {
listen 80;
server_name www.test.com;
access_log /usr/local/var/log/nginx/www.test.com.error.log combined;
error_log /usr/local/var/log/nginx/www.test.com.error.log error;
location ^~ /static/ {
root /Users/bruce/www/personal/test/static;
index index.html;
return 502 $request_filename;
}
}
或者location不用修饰符:
location /static/ {
root /Users/bruce/www/personal/test/static/;
index index.html;
return 502 $request_filename;
}
当使用root时:
访问:http://www.test.com/static/html/index.html
nginx会查找文件:/Users/bruce/www/personal/test/static/static/html/index.html。
验证:/Users/bruce/www/personal/test/static,而uri为:/static/html/index.html,它们相连接,即为:
/Users/bruce/www/personal/test/static + /static/html/index.html = /Users/bruce/www/personal/test/static/static/html/index.html
验证正确:
注意:这里的root指定的路径最后并没有/
,也就是static后面没有/
,如果有斜杠其实也是正确的,即:
/Users/bruce/www/personal/test/static/ + /static/html/index.html = /Users/bruce/www/personal/test/static//static/html/index.html
其中重复的斜杠应该是nginx自己兼容处理,直接忽略掉了(因为实际测试,最后有斜杠跟没有斜杠是一样的)。
把location匹配规则改成:
location ~ /static/ {
root /Users/bruce/www/personal/test/static;
index index.html;
return 502 $request_filename;
}
访问:http://www.test.com/static/html/index.html
nginx会查找文件:/usr/local/nginx/html/static/static/index.html
再把location的匹配规则改成:
location ~ /html/ {
root /Users/bruce/www/personal/test/static;
index index.html;
return 502 $request_filename;
}
访问:http://www.test.com/static/html/index.html
nginx会查找文件:/usr/local/nginx/html/static/static/index.html
总结root:也就是说,root指定虚拟主机目录时,与location上的修饰符无关,nginx永远会去找这个路径的文件:root+uri。
把root换成alias时:
location ^~ /static/ {
alias /Users/bruce/www/personal/test/static/;
index index.html;
return 502 $request_filename;
}
或无修饰符:
location /static/ {
alias /Users/bruce/www/personal/test/static/;
index index.html;
return 502 $request_filename;
}
访问:http://www.test.com/static/html/index.html
nginx会查找文件:/Users/bruce/www/personal/test/static/html/index.html
验证:因为alias为/Users/bruce/www/personal/test/static/,uri为/static/html/index.html,uri中location匹配的部分是static,static之后的路径为:html/index.html(注意不是/html/index.html,即html前面没有/),所以最终路径为:
/Users/bruce/www/personal/test/static/ + html/index.html=/Users/bruce/www/personal/test/static/html/index.html
验证正确:
还是上边的配置,访问:http://www.test.com/static/index.html(即static后面少了个html目录)
nginx会查找文件:/Users/bruce/www/personal/test/static/index.html
验证:这次的uri为/static/index.html,location匹配的还是static,static之后的部分是index.html
(注意是不包括index.html前面的/
的),而alias的值还是/Users/bruce/www/personal/test/static/,它们相连接即为:
/Users/bruce/www/personal/test/static/ + index.html = /Users/bruce/www/personal/test/static/index.html
验证正确:
如果配置文件的^~
改成~
:
location ~ /static/ {
alias /Users/bruce/www/personal/test/static/;
index index.html;
return 502 $request_filename;
}
访问:http://www.test.com/static/html/index.html
nginx会查找alias指定的目录(不会查找文件):/Users/bruce/www/personal/test/static/
如果你把return 502那句去掉(即不打印),则会跳转到:
http://www.test.com/static/html/index.html/
查看日志,nginx读取的路径还是alias指定的目录
再把location配置文件改成这样:
location ~ /html/ {
alias /Users/bruce/www/personal/test/static/;
index index.html;
return 502 $request_filename;
}
或
location ~* /html/ {
alias /Users/bruce/www/personal/test/static/;
index index.html;
return 502 $request_filename;
}
访问:http://www.test.com/static/html/index.html
nginx还是会查找alias指定的目录(不会查找文件):/Users/bruce/www/personal/test/static/
总结alias:当不使用修饰符或修饰符使用^~
时,是alias+location匹配的uri关键字之后部分(不包括/
),当修饰符为~
或~*
时,不管location匹配的是什么,nginx都会查找alias指定的目录而不会查找具体文件,即使有设置index index.html也没有用,所以这样配置一般是不能用的,但如果你要开启autoindex(即显示目录文件列表),倒是可以这么用。
以上所有配置均经过真机测试(nginx version: openresty/1.13.6.2),但难免会有疏漏,如有错误,恳请评论指正,我将立即修改。