nginx.conf配置

nginx.conf location 的使用

Location语法规则

指令:location [ = | ~ | ~* | ^~ ] uri { ... } 或者  location @name { ... }  ; 可存在位置:	server, location
  • = 严格匹配。如果请求匹配这个location,那么将停止搜索并立即处理此请求(匹配不上还是会继续往下搜索)
  • ~ 区分大小写匹配(可用正则表达式)
  • ~* 不区分大小写匹配(可用正则表达式)
  • !~ 区分大小写不匹配
  • !~* 不区分大小写不匹配
  • ^~ 如果把这个前缀用于一个常规字符串,那么告诉nginx 如果路径匹配那么不测试正则表达式

匹配优先级

  • 首先精确匹配 =
  • 其次前缀匹配 ^~
  • 其次是按文件中顺序的正则匹配
  • 然后匹配不带任何修饰的前缀匹配
  • 最后是交给 / 通用匹配
  • 当有匹配成功时候,停止匹配,按当前匹配规则处理请求
1.1 先普通 location ,再正则 location

location 指令 大致两种类型配置参数: “最大前缀(路径)” 和 “正则匹配”

Nginx 其实是“先匹配普通 location ,再匹配正则 location ”,但是普通 location 的匹配结果又分两种:一种是“严格精确匹配(真的url 就是我们location 后面 写的那么多 )”,官方英文说法是“ exact match ”;另一种是“最大前缀匹配( 路径前什么都不写 )”,官方英文说法是“ Literal strings match the beginning portion of the query – the most specific match will be used. ”。

严格精确匹配后不会再继续匹配正则

我们做个实验:

例题 1 :假设 nginx 的配置如下

server {
       listen       80;
       server_name  localhost;
       location / {
           root   /usr/share/nginx/html;
           index  index.html index.htm;
           deny all;
       }

       location ~ \.html$ {
           root   /usr/share/nginx/html;
           index  index.html index.htm;
           allow all;
       }
}

注意这里是linux下的配置, window下 root 后不加 /

当前目录结构如下

[root@web01 conf.d]# tree /usr/share/nginx/html
/usr/share/nginx/html
├── 50x.html
└── index.html

测试结果1

http://localhost/	403 Forbidden

说明被匹配到location / {}了,原因很简单HTTP 请求 GET / 被“严格精确”匹配到了普通 location / {} ,则会停止搜索正则 location

测试结果2

 http://localhost/index.html	Welcome to nginx

说明没有被location /匹配,否则会 403 Forbidden ,但 /index.html 的确也是以“ / ”开头的,只不过此时的普通 location / 的匹配结果是“最大前缀”匹配,所以 Nginx 会继续搜索正则 location , location ~ .html$ 表达了以 .html 结尾的都 allow all; 于是接着就访问到了实际存在的 index.html 页面

测试结果3

http://localhost/index_notfound.html	404 Not Found

同样的道理先匹配 location / {} ,但属于“普通 location 的最大前缀匹配”,于是后面被“正则 location ” location ~ .html$ {} 覆盖了,最终 allow all ; 但的确目录下不存在index_notfound.html 页面,于是 404 Not Found

测试结果4

http://localhost/index_notfound.txt  403 Forbidden

说明先匹配上了 location / {…deny all;} 尽管属于“普通 location ”的最大前缀匹配结果,继续搜索正则 location ,但是 /index.txt 不是以 .html结尾的,正则 location 失败,最终采纳普通 location 的最大前缀匹配结果,于是 deny all 了

1.2 普通 location 的“显式”严格匹配前缀“=”,不继续匹配正则前缀“ ^~

上面我们演示的普通 location 都是不加任何前缀的,其实普通 location 也可以加前缀:“ ^~ ”和“ = ”。其中“ ^~”的意思是“非正则,不需要继续正则匹配”,也就是通常我们的普通 location ,还会继续搜索正则 location (恰好严格精确匹配除外),但是 nginx 很人性化,允许配置人员通过使用 ^~ 告诉 nginx 某条普通 location ,无论最大前缀匹配,还是严格精确匹配都终止继续搜索正则 location 。
而“ = ”则表达的是普通 location 不允许“最大前缀”匹配结果,必须严格等于,严格精确匹配。所以即使严格匹配没有匹配上,也是不会继续搜索正则location的。

注意: 如果我们配置了 location = /new , 恰好请求路径也是 /new,这里就是严格精确匹配的情况,nginx 会应用 “恰好严格精确匹配停止继续搜索正则”这条规则。也就是说配置了= 后,不一定 会停止搜索正则,前提是需要匹配上这条 = 规则。

server {
       listen       80;
       server_name  localhost;
       location ^~ / {
           root   /usr/share/nginx/html;
           index  index.html index.htm;
           deny all;
       }

       location ~ \.html$ {
           root   /usr/share/nginx/html; 
           index  index.html index.htm;
           allow all;
       }
}

注意这里是linux下的配置, window下 root 后不加 /

测试结果1

http://localhost/index_notfound.html  403 Forbidden

先匹配 location ^~ / {} ,因为其是非正则,不需要继续正则匹配,所以直接停止继续匹配,进入 location ^~ / {}

1.3 普通 location 与编辑顺序无关

对于普通 location 指令,匹配规则是:最大前缀匹配(与顺序无关),如果恰好是严格精确匹配结果或者加有前缀“ ^~ ”或“ = ”(符号“ = ”只能严格匹配,不能前缀匹配),则停止搜索正则 location ;

配置 1.3.1

server {
       listen       80;
       server_name  localhost;
       location  /prefix/ {
               deny all;  
       }  
       location  /prefix/mid/ {
               allow all; 
       }  
}

配置 1.3.2

server {

       listen       80;
       server_name  localhost;
       location  /prefix/mid/ {
               allow all; 
       }  
       location  /prefix/ {
               deny all;  
       }  
}

测试结果:

前提是html文件下要有这个t.html 文件

请求配置 3.1 结果配置 3.2结果
http://localhost:80/prefix/t.html403 Forbidden403 Forbidden
http://localhost:80/prefix/mid/t.html可以拿到可以拿到

结果表明:普通 location 的匹配规则是“最大前缀”匹配,而且与编辑顺序无关。

配置 3.1

server {
       listen       80;
       server_name  localhost;
       location ~ \.html$ {
           allow all; 
       }  

       location ~ ^/prefix/.*\.html$ {
           deny all;  
       }  
}

配置 3.2

server {

       listen       80;
       server_name  localhost;
       location ~ ^/prefix/.*\.html$ {
           deny all;  
       }  

       location ~ \.html$ {
           allow all; 
       } 
}

测试结果:

前提是html文件下要有这个regextest.html 文件

请求配置 3.1 结果配置 3.2结果
http://localhost:9090/regextest.html可以拿到可以拿到
http://localhost:9090/prefix/regextest.html404 Not Found403 Forbidden
1.4 前缀@的使用“ ^~

配置如下:

server {

       listen       80;
       server_name  localhost;
        location  / {
           root   html;
           index  index.html index.htm;
           allow all;
       }
       #error_page 404 http://www.baidu.com # 直接这样是不允许的
       error_page 404 = @fallback;
       location @fallback {
           proxy_pass http://www.baidu.com;

       }
}

上述配置文件的意思是:如果请求的 URI 存在,则本 nginx 返回对应的页面;如果不存在,则把请求代理到baidu.com 上去做个弥补(注: nginx 当发现 URI 对应的页面不存在, HTTP_StatusCode 会是 404 ,此时error_page 404 指令能捕获它)。

二、 root和alias的区别

指令:root path ;可存在位置:http、server、location、if
默认值:root html

指令:alias path;可存在位置:location

alias是一个目录别名的定义,root则是最上层目录的定义。使用root时,会到root + location 寻找资源;使用alias时,会到alias后定义的目录中找资源;

alias后面必须要用“/”结束,否则会找不到文件的。而root则可有可无

location /images {
     root /data/w3;
}
  • 访问:http://localhost:9090/images/是访问/data/w3/images/index.html文件
location /images/ {
   alias /data/w3/images/;
}
  • 访问:http://localhost:9090/images/是访问/data/w3/index.html文件

记录nginx不同访问路径和代理的配置,注意有加斜杠和不加的区别

以下展示不同情况下的配置:location路径、root路径、alias路径、proxy_pass代理路径。
通过这几个配置路径地址对比,建议location后面都带上斜杠。

# 进程数量
worker_processes 1;

events {
  # 最大连接数量
  worker_connections 1024;
}

http {
  include mime.types;
  default_type application/octet-stream;
  sendfile on;
  keepalive_timeout 65;

  # 演示如何强制http跳转https
  server {
    listen 80;
    server_name test.com;

    # http强制跳转到https
    rewrite ^(.*)$ https://$server_name$1 permanent;
  }

  # 演示如何配置微信支付的校验文件
  server {
    listen 80;
    server_name localhost;

    # 默认根路径
    location / {
      root index.html;
    }
    # 微信支付校验文件,可以直接配置访问名称
    location ^~/MP_verify_2g3uEjrB5B2LIbNl.txt {
      alias /home/MP_verify_2g3uEjrB5B2LIbNl.txt;
    }
    # 微信支付校验文件,也可以通过正则配置
    location ~^/MP_verify_[a-zA-Z0-9]*\.(txt)$ {
      root /home/;
      rewrite ^/home/(.txt)$ /home/$1 last;
    }
  }

  # 演示root和alias两种配置静态资源的区别
  server {
    listen 80;
    server_name localhost;

    # 用root方式,location中的路径会拼加到root的地址后面
    # 请求路径为:http://localhost:8080/files/index.jpg    实际访问为:/home/files/index.jpg
    location ~^/files/ {
      root /home/;
      index index.html index.htm;
    }
    # 用alias方式,location中的路径不会拼加到alias的地址后面
    # 这请求路径为:http://localhost:8080/files/index.jpg    实际访问为:/home/index.jpg
    location ~^/files/ {
      alias /home/;
      index index.html index.htm;
    }
  }

  # 演示请求后台接口代理配置
  server {
    listen 8080;
    server_name localhost;

    #################### 第一种场景(代理地址不加斜杠) ####################
    # 请求路径为:http://127.0.0.1:8080/api/getUser   实际代理为:http://127.0.0.1:8000/api/getUser
    location ^~/api/ {
      proxy_pass http://127.0.0.1:8000;
      proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
      proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
    }
    # 请求路径为:http://127.0.0.1:8080/api/getUser   实际指向为:http://127.0.0.1:8000/api/getUser
    location ^~/api {
      proxy_pass http://127.0.0.1:8000;
      proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
      proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
    }

    #################### 第二种场景(代理地址+斜杠) ####################
    # 请求路径为:http://127.0.0.1:8080/api/getUser   实际代理为:http://127.0.0.1:8000/getUser
    location ^~/api/ {
      proxy_pass http://127.0.0.1:8000/;
      proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
      proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
    }
    # 请求路径为:http://127.0.0.1:8080/api/getUser   实际代理为:http://127.0.0.1:8000//getUser
    location ^~/api {
      proxy_pass http://127.0.0.1:8000/;
      proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
      proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
    }

    #################### 第三种场景(代理地址+后缀) ####################
    # 请求路径为:http://127.0.0.1:8080/api/getUser   实际代理为:http://127.0.0.1:8000/user/getUser
    location ^~/api {
      proxy_pass http://127.0.0.1:8000/user;
      proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
      proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
    }
    # 请求路径为:http://127.0.0.1:8080/api/getUser   实际代理为:http://127.0.0.1:8000/usergetUser
    location ^~/api/ {
      proxy_pass http://127.0.0.1:8000/user;
      proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
      proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
    }

    #################### 第四种场景(代理地址+后缀+斜杠) ####################
    # 请求路径为:http://127.0.0.1:8080/api/getUser   实际代理为:http://127.0.0.1:8000/user/getUser
    location ^~/api/ {
      proxy_pass http://127.0.0.1:8000/user/;
      proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
      proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
    }
    # 请求路径为:http://127.0.0.1:8080/api/getUser   实际代理为:http://127.0.0.1:8000/user//getUser
    location ^~/api {
      proxy_pass http://127.0.0.1:8000/user/;
      proxy_set_header Host $http_host; #后台可以获取到完整的ip+端口号
      proxy_set_header X-Real-IP $remote_addr; #后台可以获取到用户访问的真实ip地址
    }
  }

  # 演示前端项目如何部署nginx
  server {
    listen 8090;
    server_name localhost;

	# 默认访问
    # 部署路径:/home/web/my_demo
    # 访问路径为:http://localhost:8090/
    location / {
      try_files $uri $uri/ /index.html;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $http_host;
      root /home/web/my_demo/;
      index index.html index.htm;
    }

	# 带前缀的访问
    # 部署路径:/home/web/my_demo
    # 访问路径为:http://localhost:8090/my_demo/
    # 如果location路径最后没有配置斜杠,则浏览器输入访问地址后,路径最后会自动拼一个斜杠
    location ^~/my_demo/ {
      try_files $uri $uri/ /my_demo/index.html;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $http_host;
      root /home/web/;
      index index.html index.htm;
    }
  }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值