关于alias、root的用法
root
语法:root path
默认值: root html
配置段: http,server,location,if
例子:
静态文件地址:/home/static/html/js/demo.html
用例1:
以请求http://example.com/js/demo.html为例
location /js {
root /home/static/html;
}
具体的匹配结果为/home/static/html,然后拼接location的/js,所以拼接的结果就变成了/home/static/html/js,结合访问的url,实际访问路径就为/home/static/html/js/demo.html
用例2:最左匹配原则
location会从url最左边的路径匹配,如果一致则命中该location。只有中间匹配到不会命中。
比如请求的url为http://example.com/js/demo.html ,location为
location /js {
root /home/html/;
}
此location不会被命中,因为从url中的/static开始匹配,因为他拼接起来的目录是/home/html/js与实际的目录/home/static/html/js/有差异
用例3:index
在location内部默认配置了一条规则 index index.html,补全后如下:
location /html {
root /home/static/;
index index.html;
}
假设我们访问的url是http://example.com/html/js,匹配到了/html,实际的访问路径是/home/static/html/js,如果我们该目录下包含index.html,则会把该文件返回,
所以index的作用是当访问一个目录时,会返回该目录中index指定的文件,如果指定的index文件不存在,则返回403.
用例4:
location /js {
root /home/static/html/;
index index.html;
}
location /js/ {
root /home/static/html/;
index index.html;
}
当访问http://example.com/js的时候,实际访问路径是/home/static/html/js,然后nginx会发现js不是文件是目录,所以会主动重定向到http://example.com/static/html/js/,然后就会访问到index指定的html文件。
因此加/和不加/意义是不一样的
http://example.com/static/html/js 表示将js作为一个文件来访问,但是当他发现js是一个目录时会重定向到js/
http://example.com/static/html/js/ 表示将js作为一个目录,想要访问js下面index指定的文件
所以js既能访问到js,又能访问到js下面的index指定的html文件,而js/只能访问到后者
同理,root后面的目录末尾加/则是把它当成目录,不加斜杠则是它当作目录或者文件
故对于/的总结如下:
1、url末尾不加/,如果需要带/时依靠nginx自动帮我们重定向加/
2、location 路径不加/,这样末尾有无/的url都能匹配到
3、root指定的目录后面加/,明确表示root指定的是目录,增强配置的可读性
用例5:
关于root分别放在在http、server、location段下的情况,如何调用
配置举例:
http {
# 在 http 块下定义全局 root 路径
root /var/www/global;
server {
# 服务器监听 80 端口
listen 80;
# server_name 指令用于定义服务器名称或 IP
server_name example.com;
# 在 server 块下定义特定的 root 路径
root /var/www/server;
# 定义服务器处理请求的配置
location / {
# 此处的 root 会覆盖 http 块和 server 块中的 root 设置
root /var/www/location;
index index.html index.htm;
}
}
}
当用户请求http://example.com/时会直接请求到/var/www/location,但是如果location下没有配置root路径,则看访问的时那个server段,则匹配对应server段的root路径,此处匹配结果是/var/www/server,
如果server块没有定义root,则匹配全局路径,结果则为/var/www/global
补充一点,
nginx实现location /既能访问到txt文件,又能proxy_pass到后端服务,这个问题是在我部署小程序校验文件的时候遇到的,记录一下:
需求:https://example.com/已经proxy_pass到后端服务器了,现在需要https://example.com/ABC.txt能访问到
原始的配置是这样的
server {
listen 443;
server_name example.com;
access_log logs/testgw_access.log;
ssl on;
ssl_certificate /usr/local/ssl/conf/cert/cert.pem;
ssl_certificate_key /usr/local/ssl/nginx/conf/cert.key;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://172.22.11.159:8000;
}
}
修改后的配置:
```bash
server {
listen 443;
server_name example.com;
access_log logs/testgw_access.log;
ssl on;
ssl_certificate /usr/local/ssl/conf/cert/cert.pem;
ssl_certificate_key /usr/local/ssl/nginx/conf/cert.key;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
root /home/admin/www/wx #txt文件存放目录
location / {
try_files $uri $uri/ @router;
}
location @router {
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://172.22.11.159:8000;
}
}
访问 https://example.com/ABC.txt 时 --> try_files $uri --> try_files /ABC.txt --> /data/wx/ABC.txt --> 实现了访问
访问 https://example.com/网关转发的uri/xxx 时 --> try_files $uri --> try_files /网关转发的uri/xxx --> /home/admin/www/wx网关转发的uri/xxx 不存在 --> try_files @router --> location @router --> proxy_pass
http://172.22.11.159:8000 --> 实现了访问
alias
语法:alias path
配置段:location
用例:
location /hhh {
alias /home/static/html/;
}
当访问http://example.com/hhh/js/demo.html时,匹配到这条location,访问实际路径为/home/static/html/js/demo.html
所以location随意变化,访问的路径都是alias定义的路径。
alias其余特性,最左匹配、index、location解析url工作流程、末尾’/'与root一致。
常见问题:
当/home/static/html/js是一个文件的时候
1、location配置如下:
location /js {
alias /home/static/html/js/;
}
因为alias指定的js/ 是一个目录,而实际js是一个文件,这时候会返回404
2、又或者如下写法
location /js/ {
alias /home/static/html/js;
}
实际要访问的是/home/static/html/js/是这个目录,alias指定的又是一个文件,这时候会返回500
3、同理,location这样写:
location /js/ {
alias /home/static/html/js/;
}
实际访问的路径依然是/home/static/html/js/,是个路径,而js是个文件,则返回404